15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Performance test for SQLite. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This program reads ASCII text from a file named on the command-line. 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** It converts each SQL statement into UTF16 and submits it to SQLite 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** for evaluation. A new UTF16 database is created at the beginning of 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the program. All statements are timed using the high-resolution timer 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** built into Intel-class processors. 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** To compile this program, first compile the SQLite library separately 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** will full optimizations. For example: 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** gcc -c -O6 -DSQLITE_THREADSAFE=0 sqlite3.c 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Then link against this program. But to do optimize this program 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** because that defeats the hi-res timer. 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** gcc speedtest16.c sqlite3.o -ldl -I../src 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Then run this program with a single argument which is the name of 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a file containing SQL script that you want to test: 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** ./a.out database.db test.sql 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h> 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h> 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <ctype.h> 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h> 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sqlite3.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** hwtime.h contains inline assembler code for implementing 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** high-performance timing routines. 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "hwtime.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Convert a zero-terminated ASCII string into a zero-terminated 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** UTF-16le string. Memory to hold the returned string comes 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** from malloc() and should be freed by the caller. 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void *asciiToUtf16le(const char *z){ 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int n = strlen(z); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *z16; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, j; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) z16 = malloc( n*2 + 2 ); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=j=0; i<=n; i++){ 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) z16[j++] = z[i]; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) z16[j++] = 0; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (void*)z16; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Timers 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static sqlite_uint64 prepTime = 0; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static sqlite_uint64 runTime = 0; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static sqlite_uint64 finalizeTime = 0; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Prepare and run a single statement of SQL. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void prepareAndRun(sqlite3 *db, const char *zSql){ 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *utf16; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_stmt *pStmt; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *stmtTail; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite_uint64 iStart, iElapse; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("****************************************************************\n"); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("SQL statement: [%s]\n", zSql); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) utf16 = asciiToUtf16le(zSql); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iStart = sqlite3Hwtime(); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = sqlite3_prepare16_v2(db, utf16, -1, &pStmt, &stmtTail); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iElapse = sqlite3Hwtime() - iStart; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prepTime += iElapse; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("sqlite3_prepare16_v2() returns %d in %llu cycles\n", rc, iElapse); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc==SQLITE_OK ){ 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nRow = 0; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iStart = sqlite3Hwtime(); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( (rc=sqlite3_step(pStmt))==SQLITE_ROW ){ nRow++; } 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iElapse = sqlite3Hwtime() - iStart; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) runTime += iElapse; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("sqlite3_step() returns %d after %d rows in %llu cycles\n", 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc, nRow, iElapse); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iStart = sqlite3Hwtime(); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = sqlite3_finalize(pStmt); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iElapse = sqlite3Hwtime() - iStart; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) finalizeTime += iElapse; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("sqlite3_finalize() returns %d in %llu cycles\n", rc, iElapse); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(utf16); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int main(int argc, char **argv){ 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *utf16; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3 *db; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nSql; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zSql; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, j; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILE *in; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite_uint64 iStart, iElapse; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite_uint64 iSetup = 0; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nStmt = 0; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nByte = 0; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( argc!=3 ){ 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "Usage: %s FILENAME SQL-SCRIPT\n" 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Runs SQL-SCRIPT as UTF16 against a UTF16 database\n", 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) argv[0]); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exit(1); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in = fopen(argv[2], "r"); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fseek(in, 0L, SEEK_END); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nSql = ftell(in); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zSql = malloc( nSql+1 ); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fseek(in, 0L, SEEK_SET); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nSql = fread(zSql, 1, nSql, in); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zSql[nSql] = 0; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("SQLite version: %d\n", sqlite3_libversion_number()); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unlink(argv[1]); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) utf16 = asciiToUtf16le(argv[1]); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iStart = sqlite3Hwtime(); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = sqlite3_open16(utf16, &db); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iElapse = sqlite3Hwtime() - iStart; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iSetup = iElapse; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("sqlite3_open16() returns %d in %llu cycles\n", rc, iElapse); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(utf16); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=j=0; j<nSql; j++){ 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( zSql[j]==';' ){ 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int isComplete; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char c = zSql[j+1]; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zSql[j+1] = 0; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) isComplete = sqlite3_complete(&zSql[i]); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zSql[j+1] = c; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( isComplete ){ 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zSql[j] = 0; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( i<j && isspace(zSql[i]) ){ i++; } 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( i<j ){ 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nStmt++; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nByte += j-i; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prepareAndRun(db, &zSql[i]); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zSql[j] = ';'; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i = j+1; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iStart = sqlite3Hwtime(); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_close(db); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iElapse = sqlite3Hwtime() - iStart; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iSetup += iElapse; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("sqlite3_close() returns in %llu cycles\n", iElapse); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("\n"); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Statements run: %15d\n", nStmt); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Bytes of SQL text: %15d\n", nByte); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Total prepare time: %15llu cycles\n", prepTime); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Total run time: %15llu cycles\n", runTime); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Total finalize time: %15llu cycles\n", finalizeTime); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Open/Close time: %15llu cycles\n", iSetup); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Total Time: %15llu cycles\n", 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prepTime + runTime + finalizeTime + iSetup); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 170