1: /*
2: ** Performance test for SQLite.
3: **
4: ** This program reads ASCII text from a file named on the command-line
5: ** and submits that text to SQLite for evaluation. A new database
6: ** is created at the beginning of the program. All statements are
7: ** timed using the high-resolution timer built into Intel-class processors.
8: **
9: ** To compile this program, first compile the SQLite library separately
10: ** will full optimizations. For example:
11: **
12: ** gcc -c -O6 -DSQLITE_THREADSAFE=0 sqlite3.c
13: **
14: ** Then link against this program. But to do optimize this program
15: ** because that defeats the hi-res timer.
16: **
17: ** gcc speedtest8.c sqlite3.o -ldl -I../src
18: **
19: ** Then run this program with a single argument which is the name of
20: ** a file containing SQL script that you want to test:
21: **
22: ** ./a.out test.db test.sql
23: */
24: #include <stdio.h>
25: #include <string.h>
26: #include <stdlib.h>
27: #include <ctype.h>
28: #include <unistd.h>
29: #include <stdarg.h>
30: #include "sqlite3.h"
31:
32: #include "test_osinst.c"
33:
34: /*
35: ** Prepare and run a single statement of SQL.
36: */
37: static void prepareAndRun(sqlite3_vfs *pInstVfs, sqlite3 *db, const char *zSql){
38: sqlite3_stmt *pStmt;
39: const char *stmtTail;
40: int rc;
41: char zMessage[1024];
42: zMessage[1023] = '\0';
43:
44: sqlite3_uint64 iTime;
45:
46: sqlite3_snprintf(1023, zMessage, "sqlite3_prepare_v2: %s", zSql);
47: sqlite3_instvfs_binarylog_marker(pInstVfs, zMessage);
48:
49: iTime = sqlite3Hwtime();
50: rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &stmtTail);
51: iTime = sqlite3Hwtime() - iTime;
52: sqlite3_instvfs_binarylog_call(pInstVfs,BINARYLOG_PREPARE_V2,iTime,rc,zSql);
53:
54: if( rc==SQLITE_OK ){
55: int nRow = 0;
56:
57: sqlite3_snprintf(1023, zMessage, "sqlite3_step loop: %s", zSql);
58: sqlite3_instvfs_binarylog_marker(pInstVfs, zMessage);
59: iTime = sqlite3Hwtime();
60: while( (rc=sqlite3_step(pStmt))==SQLITE_ROW ){ nRow++; }
61: iTime = sqlite3Hwtime() - iTime;
62: sqlite3_instvfs_binarylog_call(pInstVfs, BINARYLOG_STEP, iTime, rc, zSql);
63:
64: sqlite3_snprintf(1023, zMessage, "sqlite3_finalize: %s", zSql);
65: sqlite3_instvfs_binarylog_marker(pInstVfs, zMessage);
66: iTime = sqlite3Hwtime();
67: rc = sqlite3_finalize(pStmt);
68: iTime = sqlite3Hwtime() - iTime;
69: sqlite3_instvfs_binarylog_call(pInstVfs, BINARYLOG_FINALIZE, iTime, rc, zSql);
70: }
71: }
72:
73: static int stringcompare(const char *zLeft, const char *zRight){
74: int ii;
75: for(ii=0; zLeft[ii] && zRight[ii]; ii++){
76: if( zLeft[ii]!=zRight[ii] ) return 0;
77: }
78: return( zLeft[ii]==zRight[ii] );
79: }
80:
81: static char *readScriptFile(const char *zFile, int *pnScript){
82: sqlite3_vfs *pVfs = sqlite3_vfs_find(0);
83: sqlite3_file *p;
84: int rc;
85: sqlite3_int64 nByte;
86: char *zData = 0;
87: int flags = SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_DB;
88:
89: p = (sqlite3_file *)malloc(pVfs->szOsFile);
90: rc = pVfs->xOpen(pVfs, zFile, p, flags, &flags);
91: if( rc!=SQLITE_OK ){
92: goto error_out;
93: }
94:
95: rc = p->pMethods->xFileSize(p, &nByte);
96: if( rc!=SQLITE_OK ){
97: goto close_out;
98: }
99:
100: zData = (char *)malloc(nByte+1);
101: rc = p->pMethods->xRead(p, zData, nByte, 0);
102: if( rc!=SQLITE_OK ){
103: goto close_out;
104: }
105: zData[nByte] = '\0';
106:
107: p->pMethods->xClose(p);
108: free(p);
109: *pnScript = nByte;
110: return zData;
111:
112: close_out:
113: p->pMethods->xClose(p);
114:
115: error_out:
116: free(p);
117: free(zData);
118: return 0;
119: }
120:
121: int main(int argc, char **argv){
122:
123: const char zUsageMsg[] =
124: "Usage: %s options...\n"
125: " where available options are:\n"
126: "\n"
127: " -db DATABASE-FILE (database file to operate on)\n"
128: " -script SCRIPT-FILE (script file to read sql from)\n"
129: " -log LOG-FILE (log file to create)\n"
130: " -logdata (log all data to log file)\n"
131: "\n"
132: " Options -db, -script and -log are compulsory\n"
133: "\n"
134: ;
135:
136: const char *zDb = 0;
137: const char *zScript = 0;
138: const char *zLog = 0;
139: int logdata = 0;
140:
141: int ii;
142: int i, j;
143: int rc;
144:
145: sqlite3_vfs *pInstVfs; /* Instrumentation VFS */
146:
147: char *zSql = 0;
148: int nSql;
149:
150: sqlite3 *db;
151:
152: for(ii=1; ii<argc; ii++){
153: if( stringcompare("-db", argv[ii]) && (ii+1)<argc ){
154: zDb = argv[++ii];
155: }
156:
157: else if( stringcompare("-script", argv[ii]) && (ii+1)<argc ){
158: zScript = argv[++ii];
159: }
160:
161: else if( stringcompare("-log", argv[ii]) && (ii+1)<argc ){
162: zLog = argv[++ii];
163: }
164:
165: else if( stringcompare("-logdata", argv[ii]) ){
166: logdata = 1;
167: }
168:
169: else {
170: goto usage;
171: }
172: }
173: if( !zDb || !zScript || !zLog ) goto usage;
174:
175: zSql = readScriptFile(zScript, &nSql);
176: if( !zSql ){
177: fprintf(stderr, "Failed to read script file\n");
178: return -1;
179: }
180:
181: pInstVfs = sqlite3_instvfs_binarylog("logging", 0, zLog, logdata);
182:
183: rc = sqlite3_open_v2(
184: zDb, &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, "logging"
185: );
186: if( rc!=SQLITE_OK ){
187: fprintf(stderr, "Failed to open db: %s\n", sqlite3_errmsg(db));
188: return -2;
189: }
190:
191: for(i=j=0; j<nSql; j++){
192: if( zSql[j]==';' ){
193: int isComplete;
194: char c = zSql[j+1];
195: zSql[j+1] = 0;
196: isComplete = sqlite3_complete(&zSql[i]);
197: zSql[j+1] = c;
198: if( isComplete ){
199: zSql[j] = 0;
200: while( i<j && isspace(zSql[i]) ){ i++; }
201: if( i<j ){
202: prepareAndRun(pInstVfs, db, &zSql[i]);
203: }
204: zSql[j] = ';';
205: i = j+1;
206: }
207: }
208: }
209:
210: sqlite3_instvfs_destroy(pInstVfs);
211: return 0;
212:
213: usage:
214: fprintf(stderr, zUsageMsg, argv[0]);
215: return -3;
216: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>