]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add the speedtest8inst1.c program for running speed tests with an
authordrh <drh@noemail.net>
Fri, 11 Apr 2008 21:20:48 +0000 (21:20 +0000)
committerdrh <drh@noemail.net>
Fri, 11 Apr 2008 21:20:48 +0000 (21:20 +0000)
instrumented VFS. (CVS 4993)

FossilOrigin-Name: baa8056c67c03ac78a1ed6da5a46fda793340739

manifest
manifest.uuid
tool/speedtest8inst1.c [new file with mode: 0644]

index b4875f12991f82c42cfa015311f46d633ae046e8..08c375157af04d6c6f9fff474c1944bcd83453cf 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Faster\simplementation\sof\shexToInt\sthat\suses\snot\sbranches.\s\sTicket\s#3047.\s(CVS\s4992)
-D 2008-04-11T19:37:56
+C Add\sthe\sspeedtest8inst1.c\sprogram\sfor\srunning\sspeed\stests\swith\san\ninstrumented\sVFS.\s(CVS\s4993)
+D 2008-04-11T21:20:49
 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
 F Makefile.in b861627d91df5ee422c54237aa38296954dc0151
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -569,6 +569,7 @@ F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355
 F tool/speedtest16.c 6f5bc019dcf8b6537f379bbac0408a9e1a86f0b6
 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c fe5c8aeba4f4d4a0159dadc1c3a0733c1b7e0417
+F tool/speedtest8inst1.c 025879132979a5fdec11218472cba6cf8f6ec854
 F www/34to35.tcl 942e479aa7740b55d714dce0f0b2cb6ca91c3f20
 F www/arch.fig d5f9752a4dbf242e9cfffffd3f5762b6c63b3bcf
 F www/arch.gif f845a64772062e82d17980a349f95f1f0b4c8054
@@ -627,7 +628,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P a93b7a344a713a9ed9d72be4707eb28c2979648c
-R ad4db1f58ad5d1e909c90f01c6018ce9
+P a70e9587569c99dd05e79c6745ff930aa31d763c
+R 9c5ff1287eaf10cf60991e88a0854ca2
 U drh
-Z edd38be2c3330bd5c64978b55d0e6a92
+Z daa0cde1bcb6eff40ce7d638cd073f72
index 858fea061e2d161ff0eb53c0ab589933fcfaab00..3b74290c54772ea21084822837b8e1ce01fb2454 100644 (file)
@@ -1 +1 @@
-a70e9587569c99dd05e79c6745ff930aa31d763c
\ No newline at end of file
+baa8056c67c03ac78a1ed6da5a46fda793340739
\ No newline at end of file
diff --git a/tool/speedtest8inst1.c b/tool/speedtest8inst1.c
new file mode 100644 (file)
index 0000000..2aa4838
--- /dev/null
@@ -0,0 +1,545 @@
+/*
+** Performance test for SQLite.
+**
+** This program reads ASCII text from a file named on the command-line
+** and submits that text  to SQLite for evaluation.  A new database
+** is created at the beginning of the program.  All statements are
+** timed using the high-resolution timer built into Intel-class processors.
+**
+** To compile this program, first compile the SQLite library separately
+** will full optimizations.  For example:
+**
+**     gcc -c -O6 -DSQLITE_THREADSAFE=0 sqlite3.c
+**
+** Then link against this program.  But to do optimize this program
+** because that defeats the hi-res timer.
+**
+**     gcc speedtest8.c sqlite3.o -ldl
+**
+** Then run this program with a single argument which is the name of
+** a file containing SQL script that you want to test:
+**
+**     ./a.out test.db  test.sql
+*/
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include "sqlite3.h"
+
+/*
+** The following routine only works on pentium-class processors.
+** It uses the RDTSC opcode to read the cycle count value out of the
+** processor and returns that value.  This can be used for high-res
+** profiling.
+*/
+__inline__ sqlite3_uint64 hwtime(void){
+   unsigned int lo, hi;
+   /* We cannot use "=A", since this would use %rax on x86_64 */
+   __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
+   return (sqlite3_uint64)hi << 32 | lo;
+}
+
+/*
+** Send a message to the log file.
+*/
+static void logMessage(const char *zFormat, ...){
+  va_list ap;
+  va_start(ap, zFormat);
+  vprintf(zFormat, ap);
+  va_end(ap);
+}
+
+/*
+** Timers
+*/
+static sqlite3_uint64 prepTime = 0;
+static sqlite3_uint64 runTime = 0;
+static sqlite3_uint64 finalizeTime = 0;
+static sqlite3_uint64 instTime = 0;
+
+typedef struct inst_file inst_file;
+struct inst_file {
+  sqlite3_file base;
+  sqlite3_file *pReal;
+};
+
+/*
+** Method declarations for inst_file.
+*/
+static int instClose(sqlite3_file*);
+static int instRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
+static int instWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst);
+static int instTruncate(sqlite3_file*, sqlite3_int64 size);
+static int instSync(sqlite3_file*, int flags);
+static int instFileSize(sqlite3_file*, sqlite3_int64 *pSize);
+static int instLock(sqlite3_file*, int);
+static int instUnlock(sqlite3_file*, int);
+static int instCheckReservedLock(sqlite3_file*);
+static int instFileControl(sqlite3_file*, int op, void *pArg);
+static int instSectorSize(sqlite3_file*);
+static int instDeviceCharacteristics(sqlite3_file*);
+
+/*
+** Method declarations for inst_vfs.
+*/
+static int instOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
+static int instDelete(sqlite3_vfs*, const char *zName, int syncDir);
+static int instAccess(sqlite3_vfs*, const char *zName, int flags);
+static int instGetTempName(sqlite3_vfs*, int nOut, char *zOut);
+static int instFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut);
+static void *instDlOpen(sqlite3_vfs*, const char *zFilename);
+static void instDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
+static void *instDlSym(sqlite3_vfs*,void*, const char *zSymbol);
+static void instDlClose(sqlite3_vfs*, void*);
+static int instRandomness(sqlite3_vfs*, int nByte, char *zOut);
+static int instSleep(sqlite3_vfs*, int microseconds);
+static int instCurrentTime(sqlite3_vfs*, double*);
+
+static sqlite3_vfs inst_vfs = {
+  1,                      /* iVersion */
+  0,                      /* szOsFile */
+  0,                      /* mxPathname */
+  0,                      /* pNext */
+  "instVfs",              /* zName */
+  0,                      /* pAppData */
+  instOpen,               /* xOpen */
+  instDelete,             /* xDelete */
+  instAccess,             /* xAccess */
+  instGetTempName,        /* xGetTempName */
+  instFullPathname,       /* xFullPathname */
+  instDlOpen,             /* xDlOpen */
+  instDlError,            /* xDlError */
+  instDlSym,              /* xDlSym */
+  instDlClose,            /* xDlClose */
+  instRandomness,         /* xRandomness */
+  instSleep,              /* xSleep */
+  instCurrentTime         /* xCurrentTime */
+};
+
+static sqlite3_io_methods inst_io_methods = {
+  1,                            /* iVersion */
+  instClose,                      /* xClose */
+  instRead,                       /* xRead */
+  instWrite,                      /* xWrite */
+  instTruncate,                   /* xTruncate */
+  instSync,                       /* xSync */
+  instFileSize,                   /* xFileSize */
+  instLock,                       /* xLock */
+  instUnlock,                     /* xUnlock */
+  instCheckReservedLock,          /* xCheckReservedLock */
+  instFileControl,                /* xFileControl */
+  instSectorSize,                 /* xSectorSize */
+  instDeviceCharacteristics       /* xDeviceCharacteristics */
+};
+
+#define OS_TIME_IO(MESSAGE, A, B, CALL)      \
+  int rc; sqlite3_uint64 t1, t2;             \
+  inst_file *p = (inst_file*)pFile;          \
+  t1 = hwtime();                             \
+  rc = CALL;                                 \
+  t2 = hwtime();                             \
+  logMessage(MESSAGE, A, B, t2-t1);          \
+  instTime += hwtime() - t2;                 \
+  return rc;
+
+#define OS_TIME_VFS(MESSAGE, A, B, CALL)                 \
+  int rc;                                                \
+  sqlite3_uint64 t1, t2;                                 \
+  sqlite3_vfs *pRealVfs = (sqlite3_vfs*)pVfs->pAppData;  \
+  t1 = hwtime();                                         \
+  rc = CALL;                                             \
+  t2 = hwtime();                                         \
+  logMessage(MESSAGE, A, B, t2-t1);                      \
+  instTime += hwtime() - t2;                             \
+  return rc;
+
+
+/*
+** Close an inst-file.
+*/
+static int instClose(sqlite3_file *pFile){
+  OS_TIME_IO("xClose: %s%s%lld cycles\n", "", "",
+    p->pReal->pMethods->xClose(p->pReal)
+  );
+}
+
+/*
+** Read data from an inst-file.
+*/
+static int instRead(
+  sqlite3_file *pFile, 
+  void *zBuf, 
+  int iAmt, 
+  sqlite_int64 iOfst
+){
+  OS_TIME_IO("xRead: %d bytes at offset %lld - %lld cycles\n", iAmt, iOfst, 
+    p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt,iOfst)
+  );
+}
+
+/*
+** Write data to an inst-file.
+*/
+static int instWrite(
+  sqlite3_file *pFile,
+  const void *z,
+  int iAmt,
+  sqlite_int64 iOfst
+){
+  OS_TIME_IO("xWrite: %d bytes at offset %lld - %lld cycles\n", iAmt, iOfst,
+    p->pReal->pMethods->xWrite(p->pReal, z, iAmt, iOfst)
+  );
+}
+
+/*
+** Truncate an inst-file.
+*/
+static int instTruncate(sqlite3_file *pFile, sqlite_int64 size){
+  OS_TIME_IO("xTruncate: to %lld bytes - %s%lld cycles\n", size, "",
+    p->pReal->pMethods->xTruncate(p->pReal, size)
+  );
+}
+
+/*
+** Sync an inst-file.
+*/
+static int instSync(sqlite3_file *pFile, int flags){
+  OS_TIME_IO("xSync: %s%s%lld cycles\n", "", "", 
+    p->pReal->pMethods->xSync(p->pReal, flags)
+  );
+}
+
+/*
+** Return the current file-size of an inst-file.
+*/
+static int instFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
+  OS_TIME_IO("xFileSize: %s%s%lld cycles\n", "", "", 
+    p->pReal->pMethods->xFileSize(p->pReal, pSize)
+  );
+}
+
+/*
+** Lock an inst-file.
+*/
+static int instLock(sqlite3_file *pFile, int eLock){
+  OS_TIME_IO("xLock: %d %s%lld cycles\n", eLock, "",
+    p->pReal->pMethods->xLock(p->pReal, eLock)
+  );
+}
+
+/*
+** Unlock an inst-file.
+*/
+static int instUnlock(sqlite3_file *pFile, int eLock){
+  OS_TIME_IO("xUnlock: %d %s%lld\n", eLock, "",
+    p->pReal->pMethods->xUnlock(p->pReal, eLock)
+  );
+}
+
+/*
+** Check if another file-handle holds a RESERVED lock on an inst-file.
+*/
+static int instCheckReservedLock(sqlite3_file *pFile){
+  OS_TIME_IO("xCheckReservedLock: %s%s%lld cycles\n", "", "",
+    p->pReal->pMethods->xCheckReservedLock(p->pReal)
+  );
+}
+
+/*
+** File control method. For custom operations on an inst-file.
+*/
+static int instFileControl(sqlite3_file *pFile, int op, void *pArg){
+  OS_TIME_IO("xFileControl:  op=%d - %s%lld cycles\n", op, "",
+    p->pReal->pMethods->xFileControl(p->pReal, op, pArg)
+  );
+}
+
+/*
+** Return the sector-size in bytes for an inst-file.
+*/
+static int instSectorSize(sqlite3_file *pFile){
+  OS_TIME_IO("xSectorSize: %s%s%lld cycles\n", "", "",
+    p->pReal->pMethods->xSectorSize(p->pReal)
+  );
+}
+
+/*
+** Return the device characteristic flags supported by an inst-file.
+*/
+static int instDeviceCharacteristics(sqlite3_file *pFile){
+  OS_TIME_IO("xDeviceCharacteristics: %s%s%lld cycles\n", "", "",
+    p->pReal->pMethods->xDeviceCharacteristics(p->pReal)
+  );
+}
+
+/*
+** Open an inst file handle.
+*/
+static int instOpen(
+  sqlite3_vfs *pVfs,
+  const char *zName,
+  sqlite3_file *pFile,
+  int flags,
+  int *pOutFlags
+){
+  inst_file *p = (inst_file *)pFile;
+  pFile->pMethods = &inst_io_methods;
+  p->pReal = (sqlite3_file *)&p[1];
+
+  OS_TIME_VFS("xOpen: \"%s\" flags=0x04%x - %lld cycles\n", zName, flags,
+    pRealVfs->xOpen(pRealVfs, zName, p->pReal, flags, pOutFlags)
+  );
+}
+
+/*
+** Delete the file located at zPath. If the dirSync argument is true,
+** ensure the file-system modifications are synced to disk before
+** returning.
+*/
+static int instDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
+  OS_TIME_VFS("xDelete:  \"%s\", dirSync=%d - %lld cycles\n",
+    zPath, dirSync,
+    pRealVfs->xDelete(pRealVfs, zPath, dirSync) 
+  );
+}
+
+/*
+** Test for access permissions. Return true if the requested permission
+** is available, or false otherwise.
+*/
+static int instAccess(sqlite3_vfs *pVfs, const char *zPath, int flags){
+  OS_TIME_VFS("xAccess of \"%s\", flags=0x%04x - %lld cycles\n",
+    zPath, flags,
+    pRealVfs->xAccess(pRealVfs, zPath, flags) 
+  );
+}
+
+/*
+** Populate buffer zBufOut with a pathname suitable for use as a 
+** temporary file. zBufOut is guaranteed to point to a buffer of 
+** at least (INST_MAX_PATHNAME+1) bytes.
+*/
+static int instGetTempName(sqlite3_vfs *pVfs, int nOut, char *zBufOut){
+  OS_TIME_VFS("xGetTempName: %s%s%lld cycles\n", "", "",
+    pRealVfs->xGetTempname(pRealVfs, nOut, zBufOut)
+  );
+}
+
+/*
+** Populate buffer zOut with the full canonical pathname corresponding
+** to the pathname in zPath. zOut is guaranteed to point to a buffer
+** of at least (INST_MAX_PATHNAME+1) bytes.
+*/
+static int instFullPathname(
+  sqlite3_vfs *pVfs, 
+  const char *zPath, 
+  int nOut, 
+  char *zOut
+){
+  OS_TIME_VFS("xFullPathname: \"%s\" - %s%lld cycles\n",
+    zPath, "",
+    pRealVfs->xFullPathname(pRealVfs, zPath, nOut, zOut)
+  );
+}
+
+/*
+** Open the dynamic library located at zPath and return a handle.
+*/
+static void *instDlOpen(sqlite3_vfs *pVfs, const char *zPath){
+  sqlite3_vfs *pRealVfs = (sqlite3_vfs*)pVfs->pAppData;
+  return pRealVfs->xDlOpen(pRealVfs, zPath);
+}
+
+/*
+** Populate the buffer zErrMsg (size nByte bytes) with a human readable
+** utf-8 string describing the most recent error encountered associated 
+** with dynamic libraries.
+*/
+static void instDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
+  sqlite3_vfs *pRealVfs = (sqlite3_vfs*)pVfs->pAppData;
+  pRealVfs->xDlError(pRealVfs, nByte, zErrMsg);
+}
+
+/*
+** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
+*/
+static void *instDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){
+  sqlite3_vfs *pRealVfs = (sqlite3_vfs*)pVfs->pAppData;
+  return pRealVfs->xDlSym(pRealVfs, pHandle, zSymbol);
+}
+
+/*
+** Close the dynamic library handle pHandle.
+*/
+static void instDlClose(sqlite3_vfs *pVfs, void *pHandle){
+  sqlite3_vfs *pRealVfs = (sqlite3_vfs*)pVfs->pAppData;
+  pRealVfs->xDlClose(pRealVfs, pHandle);
+}
+
+/*
+** Populate the buffer pointed to by zBufOut with nByte bytes of 
+** random data.
+*/
+static int instRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
+  OS_TIME_VFS("xRandomness:  nByte=%d - %s%lld cycles\n", nByte, "",
+    pRealVfs->xRandomness(pRealVfs, nByte, zBufOut)
+  );
+}
+
+/*
+** Sleep for nMicro microseconds. Return the number of microseconds 
+** actually slept.
+*/
+static int instSleep(sqlite3_vfs *pVfs, int nMicro){
+  OS_TIME_VFS("xSleep:  usec=%d - %s%lld cycles\n", nMicro, "",
+    pRealVfs->xSleep(pRealVfs, nMicro) 
+  );
+}
+
+/*
+** Return the current time as a Julian Day number in *pTimeOut.
+*/
+static int instCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
+  OS_TIME_VFS("xCurrentTime:  %s%s%lld cycles\n", "", "",
+    pRealVfs->xCurrentTime(pRealVfs, pTimeOut) 
+  );
+}
+
+/*
+** Insert the instructed VFS as the default VFS.
+*/
+static void setupInstrumentedVfs(void){
+  sqlite3_vfs *p;
+  sqlite3_vfs *pParent;
+
+  pParent = sqlite3_vfs_find(0);
+  if( !pParent ){
+    return;
+  }
+
+  p = sqlite3_malloc(sizeof(inst_vfs));
+  if( p ){
+    *p = inst_vfs;
+    p->szOsFile = pParent->szOsFile + sizeof(inst_file);
+    p->mxPathname = pParent->mxPathname;
+    p->pAppData = pParent;
+    sqlite3_vfs_register(p, 1);
+  }
+}
+
+
+/*
+** Prepare and run a single statement of SQL.
+*/
+static void prepareAndRun(sqlite3 *db, const char *zSql){
+  sqlite3_stmt *pStmt;
+  const char *stmtTail;
+  sqlite3_uint64 iStart, iElapse;
+  int rc;
+  
+  printf("****************************************************************\n");
+  printf("SQL statement: [%s]\n", zSql);
+  instTime = 0;
+  iStart = hwtime();
+  rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &stmtTail);
+  iElapse = hwtime();
+  iElapse -= iStart + instTime;
+  prepTime += iElapse;
+  printf("sqlite3_prepare_v2() returns %d in %llu cycles\n", rc, iElapse);
+  if( rc==SQLITE_OK ){
+    int nRow = 0;
+    instTime = 0;
+    iStart = hwtime();
+    while( (rc=sqlite3_step(pStmt))==SQLITE_ROW ){ nRow++; }
+    iElapse = hwtime();
+    iElapse -= iStart + instTime;
+    runTime += iElapse;
+    printf("sqlite3_step() returns %d after %d rows in %llu cycles\n",
+           rc, nRow, iElapse);
+    instTime = 0;
+    iStart = hwtime();
+    rc = sqlite3_finalize(pStmt);
+    iElapse = hwtime();
+    iElapse -= iStart + instTime;
+    finalizeTime += iElapse;
+    printf("sqlite3_finalize() returns %d in %llu cycles\n", rc, iElapse);
+  }
+}
+
+int main(int argc, char **argv){
+  sqlite3 *db;
+  int rc;
+  int nSql;
+  char *zSql;
+  int i, j;
+  FILE *in;
+  sqlite3_uint64 iStart, iElapse;
+  sqlite3_uint64 iSetup = 0;
+  int nStmt = 0;
+  int nByte = 0;
+
+  if( argc!=3 ){
+    fprintf(stderr, "Usage: %s FILENAME SQL-SCRIPT\n"
+                    "Runs SQL-SCRIPT against a UTF8 database\n",
+                    argv[0]);
+    exit(1);
+  }
+  in = fopen(argv[2], "r");
+  fseek(in, 0L, SEEK_END);
+  nSql = ftell(in);
+  zSql = malloc( nSql+1 );
+  fseek(in, 0L, SEEK_SET);
+  nSql = fread(zSql, 1, nSql, in);
+  zSql[nSql] = 0;
+
+  printf("SQLite version: %d\n", sqlite3_libversion_number());
+  unlink(argv[1]);
+  setupInstrumentedVfs();
+  instTime = 0;
+  iStart = hwtime();
+  rc = sqlite3_open(argv[1], &db);
+  iElapse = hwtime();
+  iElapse -= iStart + instTime;
+  iSetup = iElapse;
+  printf("sqlite3_open() returns %d in %llu cycles\n", rc, iElapse);
+  for(i=j=0; j<nSql; j++){
+    if( zSql[j]==';' ){
+      int isComplete;
+      char c = zSql[j+1];
+      zSql[j+1] = 0;
+      isComplete = sqlite3_complete(&zSql[i]);
+      zSql[j+1] = c;
+      if( isComplete ){
+        zSql[j] = 0;
+        while( i<j && isspace(zSql[i]) ){ i++; }
+        if( i<j ){
+          nStmt++;
+          nByte += j-i;
+          prepareAndRun(db, &zSql[i]);
+        }
+        zSql[j] = ';';
+        i = j+1;
+      }
+    }
+  }
+  instTime = 0;
+  iStart = hwtime();
+  sqlite3_close(db);
+  iElapse = hwtime();
+  iElapse -= iStart + instTime;
+  iSetup += iElapse;
+  printf("sqlite3_close() returns in %llu cycles\n", iElapse);
+  printf("\n");
+  printf("Statements run:       %15d\n", nStmt);
+  printf("Bytes of SQL text:    %15d\n", nByte);
+  printf("Total prepare time:   %15llu cycles\n", prepTime);
+  printf("Total run time:       %15llu cycles\n", runTime);
+  printf("Total finalize time:  %15llu cycles\n", finalizeTime);
+  printf("Open/Close time:      %15llu cycles\n", iSetup);
+  printf("Total Time:           %15llu cycles\n",
+      prepTime + runTime + finalizeTime + iSetup);
+  return 0;
+}