| OLD | NEW | 
 | (Empty) | 
|    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.tm
     s_utime)/(double)CLOCKS_PER_SEC ); |  | 
|  248   printf("Total system CPU time: %15.3g secs\n", (tmsEnd.tms_stime - tmsStart.tm
     s_stime)/(double)CLOCKS_PER_SEC ); |  | 
|  249   printf("Total real time:       %15.3g secs\n", (clkEnd -clkStart)/(double)CLOC
     KS_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 } |  | 
| OLD | NEW |