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 <time.h>
29:
30: #if defined(_MSC_VER)
31: #include <windows.h>
32: #else
33: #include <unistd.h>
34: #include <sys/times.h>
35: #include <sched.h>
36: #endif
37:
38: #include "sqlite3.h"
39:
40: /*
41: ** hwtime.h contains inline assembler code for implementing
42: ** high-performance timing routines.
43: */
44: #include "hwtime.h"
45:
46: /*
47: ** Timers
48: */
49: static sqlite_uint64 prepTime = 0;
50: static sqlite_uint64 runTime = 0;
51: static sqlite_uint64 finalizeTime = 0;
52:
53: /*
54: ** Prepare and run a single statement of SQL.
55: */
56: static void prepareAndRun(sqlite3 *db, const char *zSql, int bQuiet){
57: sqlite3_stmt *pStmt;
58: const char *stmtTail;
59: sqlite_uint64 iStart, iElapse;
60: int rc;
61:
62: if (!bQuiet){
63: printf("***************************************************************\n");
64: }
65: if (!bQuiet) printf("SQL statement: [%s]\n", zSql);
66: iStart = sqlite3Hwtime();
67: rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &stmtTail);
68: iElapse = sqlite3Hwtime() - iStart;
69: prepTime += iElapse;
70: if (!bQuiet){
71: printf("sqlite3_prepare_v2() returns %d in %llu cycles\n", rc, iElapse);
72: }
73: if( rc==SQLITE_OK ){
74: int nRow = 0;
75: iStart = sqlite3Hwtime();
76: while( (rc=sqlite3_step(pStmt))==SQLITE_ROW ){ nRow++; }
77: iElapse = sqlite3Hwtime() - iStart;
78: runTime += iElapse;
79: if (!bQuiet){
80: printf("sqlite3_step() returns %d after %d rows in %llu cycles\n",
81: rc, nRow, iElapse);
82: }
83: iStart = sqlite3Hwtime();
84: rc = sqlite3_finalize(pStmt);
85: iElapse = sqlite3Hwtime() - iStart;
86: finalizeTime += iElapse;
87: if (!bQuiet){
88: printf("sqlite3_finalize() returns %d in %llu cycles\n", rc, iElapse);
89: }
90: }
91: }
92:
93: int main(int argc, char **argv){
94: sqlite3 *db;
95: int rc;
96: int nSql;
97: char *zSql;
98: int i, j;
99: FILE *in;
100: sqlite_uint64 iStart, iElapse;
101: sqlite_uint64 iSetup = 0;
102: int nStmt = 0;
103: int nByte = 0;
104: const char *zArgv0 = argv[0];
105: int bQuiet = 0;
106: #if !defined(_MSC_VER)
107: struct tms tmsStart, tmsEnd;
108: clock_t clkStart, clkEnd;
109: #endif
110:
111: #ifdef HAVE_OSINST
112: extern sqlite3_vfs *sqlite3_instvfs_binarylog(char *, char *, char *);
113: extern void sqlite3_instvfs_destroy(sqlite3_vfs *);
114: sqlite3_vfs *pVfs = 0;
115: #endif
116:
117: while (argc>3)
118: {
119: #ifdef HAVE_OSINST
120: if( argc>4 && (strcmp(argv[1], "-log")==0) ){
121: pVfs = sqlite3_instvfs_binarylog("oslog", 0, argv[2]);
122: sqlite3_vfs_register(pVfs, 1);
123: argv += 2;
124: argc -= 2;
125: continue;
126: }
127: #endif
128:
129: /*
130: ** Increasing the priority slightly above normal can help with
131: ** repeatability of testing. Note that with Cygwin, -5 equates
132: ** to "High", +5 equates to "Low", and anything in between
133: ** equates to "Normal".
134: */
135: if( argc>4 && (strcmp(argv[1], "-priority")==0) ){
136: #if defined(_MSC_VER)
137: int new_priority = atoi(argv[2]);
138: if(!SetPriorityClass(GetCurrentProcess(),
139: (new_priority<=-5) ? HIGH_PRIORITY_CLASS :
140: (new_priority<=0) ? ABOVE_NORMAL_PRIORITY_CLASS :
141: (new_priority==0) ? NORMAL_PRIORITY_CLASS :
142: (new_priority<5) ? BELOW_NORMAL_PRIORITY_CLASS :
143: IDLE_PRIORITY_CLASS)){
144: printf ("error setting priority\n");
145: exit(2);
146: }
147: #else
148: struct sched_param myParam;
149: sched_getparam(0, &myParam);
150: printf ("Current process priority is %d.\n", (int)myParam.sched_priority);
151: myParam.sched_priority = atoi(argv[2]);
152: printf ("Setting process priority to %d.\n", (int)myParam.sched_priority);
153: if (sched_setparam (0, &myParam) != 0){
154: printf ("error setting priority\n");
155: exit(2);
156: }
157: #endif
158: argv += 2;
159: argc -= 2;
160: continue;
161: }
162:
163: if( argc>3 && strcmp(argv[1], "-quiet")==0 ){
164: bQuiet = -1;
165: argv++;
166: argc--;
167: continue;
168: }
169:
170: break;
171: }
172:
173: if( argc!=3 ){
174: fprintf(stderr, "Usage: %s [options] FILENAME SQL-SCRIPT\n"
175: "Runs SQL-SCRIPT against a UTF8 database\n"
176: "\toptions:\n"
177: #ifdef HAVE_OSINST
178: "\t-log <log>\n"
179: #endif
180: "\t-priority <value> : set priority of task\n"
181: "\t-quiet : only display summary results\n",
182: zArgv0);
183: exit(1);
184: }
185:
186: in = fopen(argv[2], "r");
187: fseek(in, 0L, SEEK_END);
188: nSql = ftell(in);
189: zSql = malloc( nSql+1 );
190: fseek(in, 0L, SEEK_SET);
191: nSql = fread(zSql, 1, nSql, in);
192: zSql[nSql] = 0;
193:
194: printf("SQLite version: %d\n", sqlite3_libversion_number());
195: unlink(argv[1]);
196: #if !defined(_MSC_VER)
197: clkStart = times(&tmsStart);
198: #endif
199: iStart = sqlite3Hwtime();
200: rc = sqlite3_open(argv[1], &db);
201: iElapse = sqlite3Hwtime() - iStart;
202: iSetup = iElapse;
203: if (!bQuiet) printf("sqlite3_open() returns %d in %llu cycles\n", rc, iElapse);
204: for(i=j=0; j<nSql; j++){
205: if( zSql[j]==';' ){
206: int isComplete;
207: char c = zSql[j+1];
208: zSql[j+1] = 0;
209: isComplete = sqlite3_complete(&zSql[i]);
210: zSql[j+1] = c;
211: if( isComplete ){
212: zSql[j] = 0;
213: while( i<j && isspace(zSql[i]) ){ i++; }
214: if( i<j ){
215: int n = j - i;
216: if( n>=6 && memcmp(&zSql[i], ".crash",6)==0 ) exit(1);
217: nStmt++;
218: nByte += n;
219: prepareAndRun(db, &zSql[i], bQuiet);
220: }
221: zSql[j] = ';';
222: i = j+1;
223: }
224: }
225: }
226: iStart = sqlite3Hwtime();
227: sqlite3_close(db);
228: iElapse = sqlite3Hwtime() - iStart;
229: #if !defined(_MSC_VER)
230: clkEnd = times(&tmsEnd);
231: #endif
232: iSetup += iElapse;
233: if (!bQuiet) printf("sqlite3_close() returns in %llu cycles\n", iElapse);
234:
235: printf("\n");
236: printf("Statements run: %15d stmts\n", nStmt);
237: printf("Bytes of SQL text: %15d bytes\n", nByte);
238: printf("Total prepare time: %15llu cycles\n", prepTime);
239: printf("Total run time: %15llu cycles\n", runTime);
240: printf("Total finalize time: %15llu cycles\n", finalizeTime);
241: printf("Open/Close time: %15llu cycles\n", iSetup);
242: printf("Total time: %15llu cycles\n",
243: prepTime + runTime + finalizeTime + iSetup);
244:
245: #if !defined(_MSC_VER)
246: printf("\n");
247: printf("Total user CPU time: %15.3g secs\n", (tmsEnd.tms_utime - tmsStart.tms_utime)/(double)CLOCKS_PER_SEC );
248: printf("Total system CPU time: %15.3g secs\n", (tmsEnd.tms_stime - tmsStart.tms_stime)/(double)CLOCKS_PER_SEC );
249: printf("Total real time: %15.3g secs\n", (clkEnd -clkStart)/(double)CLOCKS_PER_SEC );
250: #endif
251:
252: #ifdef HAVE_OSINST
253: if( pVfs ){
254: sqlite3_instvfs_destroy(pVfs);
255: printf("vfs log written to %s\n", argv[0]);
256: }
257: #endif
258:
259: return 0;
260: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>