SQLite

Check-in [9883b406ce]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Consolidated inline assembly versions of "hwtime()" into hwtime.h. Provided MSVC version. Modified code for consistent use of hwtime(). Changed implementation to use sqlite_uint64 and sqlite_int64 instead of unsigned long long int and long long int for MSVC compiler support. (CVS 5178)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 9883b406ce24eae93942ee5e6aab33fb6b05329f
User & Date: shane 2008-05-29 20:22:36.000
Original User & Date: shane 2008-05-29 20:22:37.000
Context
2008-05-29
20:22
Consolidated inline assembly versions of "hwtime()" into hwtime.h. Provided MSVC version. Modified code for consistent use of hwtime(). Changed implementation to use sqlite_uint64 and sqlite_int64 instead of unsigned long long int and long long int for MSVC compiler support. (CVS 5179) (check-in: 19f5f571dd user: shane tags: trunk)
20:22
Consolidated inline assembly versions of "hwtime()" into hwtime.h. Provided MSVC version. Modified code for consistent use of hwtime(). Changed implementation to use sqlite_uint64 and sqlite_int64 instead of unsigned long long int and long long int for MSVC compiler support. (CVS 5178) (check-in: 9883b406ce user: shane tags: trunk)
05:23
Fix cosmetic issues spotted while working on ticket #3146 (CVS 5177) (check-in: 5f6eab65db user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to Makefile.in.
190
191
192
193
194
195
196

197
198
199
200
201
202
203
  $(TOP)/src/date.c \
  $(TOP)/src/delete.c \
  $(TOP)/src/expr.c \
  $(TOP)/src/fault.c \
  $(TOP)/src/func.c \
  $(TOP)/src/hash.c \
  $(TOP)/src/hash.h \

  $(TOP)/src/insert.c \
  $(TOP)/src/journal.c \
  $(TOP)/src/legacy.c \
  $(TOP)/src/loadext.c \
  $(TOP)/src/main.c \
  $(TOP)/src/malloc.c \
  $(TOP)/src/mem1.c \







>







190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
  $(TOP)/src/date.c \
  $(TOP)/src/delete.c \
  $(TOP)/src/expr.c \
  $(TOP)/src/fault.c \
  $(TOP)/src/func.c \
  $(TOP)/src/hash.c \
  $(TOP)/src/hash.h \
  $(TOP)/src/hwtime.h \
  $(TOP)/src/insert.c \
  $(TOP)/src/journal.c \
  $(TOP)/src/legacy.c \
  $(TOP)/src/loadext.c \
  $(TOP)/src/main.c \
  $(TOP)/src/malloc.c \
  $(TOP)/src/mem1.c \
358
359
360
361
362
363
364

365
366
367
368
369
370
371
# Header files used by all library source files.
#
HDR = \
   sqlite3.h  \
   $(TOP)/src/btree.h \
   $(TOP)/src/btreeInt.h \
   $(TOP)/src/hash.h \

   $(TOP)/src/sqliteLimit.h \
   $(TOP)/src/mutex.h \
   opcodes.h \
   $(TOP)/src/os.h \
   $(TOP)/src/os_common.h \
   $(TOP)/src/sqlite3ext.h \
   $(TOP)/src/sqliteInt.h  \







>







359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
# Header files used by all library source files.
#
HDR = \
   sqlite3.h  \
   $(TOP)/src/btree.h \
   $(TOP)/src/btreeInt.h \
   $(TOP)/src/hash.h \
   $(TOP)/src/hwtime.h \
   $(TOP)/src/sqliteLimit.h \
   $(TOP)/src/mutex.h \
   opcodes.h \
   $(TOP)/src/os.h \
   $(TOP)/src/os_common.h \
   $(TOP)/src/sqlite3ext.h \
   $(TOP)/src/sqliteInt.h  \
Changes to main.mk.
97
98
99
100
101
102
103

104
105
106
107
108
109
110
  $(TOP)/src/date.c \
  $(TOP)/src/delete.c \
  $(TOP)/src/expr.c \
  $(TOP)/src/fault.c \
  $(TOP)/src/func.c \
  $(TOP)/src/hash.c \
  $(TOP)/src/hash.h \

  $(TOP)/src/insert.c \
  $(TOP)/src/journal.c \
  $(TOP)/src/legacy.c \
  $(TOP)/src/loadext.c \
  $(TOP)/src/main.c \
  $(TOP)/src/malloc.c \
  $(TOP)/src/mem1.c \







>







97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
  $(TOP)/src/date.c \
  $(TOP)/src/delete.c \
  $(TOP)/src/expr.c \
  $(TOP)/src/fault.c \
  $(TOP)/src/func.c \
  $(TOP)/src/hash.c \
  $(TOP)/src/hash.h \
  $(TOP)/src/hwtime.h \
  $(TOP)/src/insert.c \
  $(TOP)/src/journal.c \
  $(TOP)/src/legacy.c \
  $(TOP)/src/loadext.c \
  $(TOP)/src/main.c \
  $(TOP)/src/malloc.c \
  $(TOP)/src/mem1.c \
246
247
248
249
250
251
252

253
254
255
256
257
258
259

# Header files used by all library source files.
#
HDR = \
   $(TOP)/src/btree.h \
   $(TOP)/src/btreeInt.h \
   $(TOP)/src/hash.h \

   keywordhash.h \
   $(TOP)/src/mutex.h \
   opcodes.h \
   $(TOP)/src/os.h \
   $(TOP)/src/os_common.h \
   $(TOP)/src/pager.h \
   parse.h  \







>







247
248
249
250
251
252
253
254
255
256
257
258
259
260
261

# Header files used by all library source files.
#
HDR = \
   $(TOP)/src/btree.h \
   $(TOP)/src/btreeInt.h \
   $(TOP)/src/hash.h \
   $(TOP)/src/hwtime.h \
   keywordhash.h \
   $(TOP)/src/mutex.h \
   opcodes.h \
   $(TOP)/src/os.h \
   $(TOP)/src/os_common.h \
   $(TOP)/src/pager.h \
   parse.h  \
Added src/hwtime.h.


































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/*
** 2008 May 27
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file contains inline asm code for retrieving "high-performance"
** counters for x86 class CPUs.
**
** $Id: hwtime.h,v 1.1 2008/05/29 20:22:37 shane Exp $
*/
#ifndef _HWTIME_H_
#define _HWTIME_H_

/*
** The following routine only works on pentium-class (or newer) 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.
*/
#if (defined(__GNUC__) || defined(_MSC_VER)) && \
      (defined(i386) || defined(__i386__) || defined(_M_IX86))

  #if defined(__GNUC__)

  __inline__ sqlite_uint64 sqlite3Hwtime(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 (sqlite_uint64)hi << 32 | lo;
  }

  #elif defined(_MSC_VER)

  __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){
     __asm {
        rdtsc
        ret       ; return value at EDX:EAX
     }
  }

  #endif

#else

  #error Need implementation of sqlite3Hwtime() for your platform.

  /*
  ** To compile without implementing sqlite3Hwtime() for your platform,
  ** you can remove the above #error and use the following
  ** stub function.  You will lose timing support for many
  ** of the debugging and testing utilities, but it should at
  ** least compile and run.
  */
  sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }

#endif

#endif /* !defined(_HWTIME_H_) */
Changes to src/os_common.h.
13
14
15
16
17
18
19
20
21


22
23
24
25
26
27
28
** This file contains macros and a little bit of code that is common to
** all of the platform-specific files (os_*.c) and is #included into those
** files.
**
** This file should be #included by the os_*.c files only.  It is not a
** general purpose header file.
**
** $Id: os_common.h,v 1.36 2008/05/16 04:51:55 danielk1977 Exp $
*/



/*
** At least two bugs have slipped in because we changed the MEMORY_DEBUG
** macro to SQLITE_DEBUG and some older makefiles have not yet made the
** switch.  The following code should catch this problem at compile-time.
*/
#ifdef MEMORY_DEBUG







|

>
>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
** This file contains macros and a little bit of code that is common to
** all of the platform-specific files (os_*.c) and is #included into those
** files.
**
** This file should be #included by the os_*.c files only.  It is not a
** general purpose header file.
**
** $Id: os_common.h,v 1.37 2008/05/29 20:22:37 shane Exp $
*/
#ifndef _OS_COMMON_H_
#define _OS_COMMON_H_

/*
** At least two bugs have slipped in because we changed the MEMORY_DEBUG
** macro to SQLITE_DEBUG and some older makefiles have not yet made the
** switch.  The following code should catch this problem at compile-time.
*/
#ifdef MEMORY_DEBUG
60
61
62
63
64
65
66
67
68

69
70
71

72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#endif

/*
** Macros for performance tracing.  Normally turned off.  Only works
** on i486 hardware.
*/
#ifdef SQLITE_PERFORMANCE_TRACE
__inline__ unsigned long long int hwtime(void){
  unsigned long long int x;

  __asm__("rdtsc\n\t"
          "mov %%edx, %%ecx\n\t"
          :"=A" (x));

  return x;
}
static unsigned long long int g_start;
static unsigned int elapse;
#define TIMER_START       g_start=hwtime()
#define TIMER_END         elapse=hwtime()-g_start
#define TIMER_ELAPSED     elapse
#else
#define TIMER_START
#define TIMER_END
#define TIMER_ELAPSED     0
#endif

/*
** If we compile with the SQLITE_TEST macro set, then the following block
** of code will give us the ability to simulate a disk I/O error.  This
** is used for testing the I/O recovery logic.
*/







|
<
>
|
|
<
>
|
|
|
|
|
|
|



|







62
63
64
65
66
67
68
69

70
71
72

73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#endif

/*
** Macros for performance tracing.  Normally turned off.  Only works
** on i486 hardware.
*/
#ifdef SQLITE_PERFORMANCE_TRACE


/* 
** hwtime.h contains inline assembler code for implementing 
** high-performance timing routines.

*/
#include "hwtime.h"

static sqlite_uint64 g_start;
static sqlite_uint64 g_elapsed;
#define TIMER_START       g_start=sqlite3Hwtime()
#define TIMER_END         g_elapsed=sqlite3Hwtime()-g_start
#define TIMER_ELAPSED     g_elapsed
#else
#define TIMER_START
#define TIMER_END
#define TIMER_ELAPSED     ((sqlite_uint64)0)
#endif

/*
** If we compile with the SQLITE_TEST macro set, then the following block
** of code will give us the ability to simulate a disk I/O error.  This
** is used for testing the I/O recovery logic.
*/
127
128
129
130
131
132
133


*/
#ifdef SQLITE_TEST
int sqlite3_open_file_count = 0;
#define OpenCounter(X)  sqlite3_open_file_count+=(X)
#else
#define OpenCounter(X)
#endif









>
>
129
130
131
132
133
134
135
136
137
*/
#ifdef SQLITE_TEST
int sqlite3_open_file_count = 0;
#define OpenCounter(X)  sqlite3_open_file_count+=(X)
#else
#define OpenCounter(X)
#endif

#endif /* !defined(_OS_COMMON_H_) */
Changes to src/os_unix.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file contains code that is specific to Unix systems.
**
** $Id: os_unix.c,v 1.182 2008/05/16 04:51:55 danielk1977 Exp $
*/
#include "sqliteInt.h"
#if OS_UNIX              /* This file is used on unix only */

/* #define SQLITE_ENABLE_LOCKING_STYLE 0 */

/*







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file contains code that is specific to Unix systems.
**
** $Id: os_unix.c,v 1.183 2008/05/29 20:22:37 shane Exp $
*/
#include "sqliteInt.h"
#if OS_UNIX              /* This file is used on unix only */

/* #define SQLITE_ENABLE_LOCKING_STYLE 0 */

/*
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
  SimulateIOError( newOffset-- );
  if( newOffset!=offset ){
    return -1;
  }
  got = read(id->h, pBuf, cnt);
#endif
  TIMER_END;
  OSTRACE5("READ    %-3d %5d %7lld %d\n", id->h, got, offset, TIMER_ELAPSED);
  return got;
}

/*
** Read data from a file into a buffer.  Return SQLITE_OK if all
** bytes were read successfully and SQLITE_IOERR if anything goes
** wrong.







|







801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
  SimulateIOError( newOffset-- );
  if( newOffset!=offset ){
    return -1;
  }
  got = read(id->h, pBuf, cnt);
#endif
  TIMER_END;
  OSTRACE5("READ    %-3d %5d %7lld %llu\n", id->h, got, offset, TIMER_ELAPSED);
  return got;
}

/*
** Read data from a file into a buffer.  Return SQLITE_OK if all
** bytes were read successfully and SQLITE_IOERR if anything goes
** wrong.
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
  newOffset = lseek(id->h, offset, SEEK_SET);
  if( newOffset!=offset ){
    return -1;
  }
  got = write(id->h, pBuf, cnt);
#endif
  TIMER_END;
  OSTRACE5("WRITE   %-3d %5d %7lld %d\n", id->h, got, offset, TIMER_ELAPSED);
  return got;
}


/*
** Write data from a buffer into a file.  Return SQLITE_OK on success
** or some other error code on failure.







|







849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
  newOffset = lseek(id->h, offset, SEEK_SET);
  if( newOffset!=offset ){
    return -1;
  }
  got = write(id->h, pBuf, cnt);
#endif
  TIMER_END;
  OSTRACE5("WRITE   %-3d %5d %7lld %llu\n", id->h, got, offset, TIMER_ELAPSED);
  return got;
}


/*
** Write data from a buffer into a file.  Return SQLITE_OK on success
** or some other error code on failure.
Changes to src/test_osinst.c.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
**
******************************************************************************
**
** This file contains the implementation of an SQLite vfs wrapper that
** adds instrumentation to all vfs and file methods. C and Tcl interfaces
** are provided to control the instrumentation.
**
** $Id: test_osinst.c,v 1.11 2008/05/16 04:51:55 danielk1977 Exp $
*/

/*
** C interface:
**
**   sqlite3_instvfs_create()
**   sqlite3_instvfs_destroy()







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
**
******************************************************************************
**
** This file contains the implementation of an SQLite vfs wrapper that
** adds instrumentation to all vfs and file methods. C and Tcl interfaces
** are provided to control the instrumentation.
**
** $Id: test_osinst.c,v 1.12 2008/05/29 20:22:37 shane Exp $
*/

/*
** C interface:
**
**   sqlite3_instvfs_create()
**   sqlite3_instvfs_destroy()
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
**       been created by an earlier invocation of [sqlite3_instvfs create].
**       After a callback script has been configured, it is invoked each
**       time a vfs or file method is called by SQLite. Before invoking
**       the callback script, five arguments are appended to it:
**
**         * The name of the invoked method - i.e. "xRead".
**
**         * The time consumed by the method call as measured by hwtime() (an
**           integer value)
**
**         * A string value with a different meaning for different calls. 
**           For file methods, the name of the file being operated on. For
**           other methods it is the filename argument, if any.
**
**         * A 32-bit integer value with a call-specific meaning.
**







|
|







49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
**       been created by an earlier invocation of [sqlite3_instvfs create].
**       After a callback script has been configured, it is invoked each
**       time a vfs or file method is called by SQLite. Before invoking
**       the callback script, five arguments are appended to it:
**
**         * The name of the invoked method - i.e. "xRead".
**
**         * The time consumed by the method call as measured by 
**           sqlite3Hwtime() (an integer value)
**
**         * A string value with a different meaning for different calls. 
**           For file methods, the name of the file being operated on. For
**           other methods it is the filename argument, if any.
**
**         * A 32-bit integer value with a call-specific meaning.
**
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
**       with vfs $NAME. The report format is a list with one element
**       for each method call (xWrite, xRead etc.). Each element is
**       itself a list with three elements:
**
**         * The name of the method call - i.e. "xWrite",
**         * The total number of calls to the method (an integer).
**         * The aggregate time consumed by all calls to the method as
**           measured by hwtime() (an integer).
*/

#include "sqlite3.h"
#include <string.h>
#include <assert.h>

/*







|







78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
**       with vfs $NAME. The report format is a list with one element
**       for each method call (xWrite, xRead etc.). Each element is
**       itself a list with three elements:
**
**         * The name of the method call - i.e. "xWrite",
**         * The total number of calls to the method (an integer).
**         * The aggregate time consumed by all calls to the method as
**           measured by sqlite3Hwtime() (an integer).
*/

#include "sqlite3.h"
#include <string.h>
#include <assert.h>

/*
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
  instUnlock,                     /* xUnlock */
  instCheckReservedLock,          /* xCheckReservedLock */
  instFileControl,                /* xFileControl */
  instSectorSize,                 /* xSectorSize */
  instDeviceCharacteristics       /* xDeviceCharacteristics */
};

/*
** 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.
*/
#if defined(i386) || defined(__i386__) || defined(_M_IX86)
__inline__ unsigned long long int osinst_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 (unsigned long long int)hi << 32 | lo;
}
#else
  static unsigned long long int osinst_hwtime(void){ return 0; }
#endif

#define OS_TIME_IO(eEvent, A, B, Call) {     \
  inst_file *p = (inst_file *)pFile;         \
  InstVfs *pInstVfs = p->pInstVfs;           \
  int rc;                                    \
  sqlite3_int64 t = osinst_hwtime();         \
  rc = Call;                                 \
  t = osinst_hwtime() - t;                   \
  pInstVfs->aTime[eEvent] += t;              \
  pInstVfs->aCount[eEvent] += 1;             \
  if( pInstVfs->xCall ){                     \
    pInstVfs->xCall(                         \
      pInstVfs->pClient,eEvent,p->iFileId,t,rc,p->zName,p->flags,A,B  \
    );                                       \
  }                                          \
  return rc;                                 \
}

#define OS_TIME_VFS(eEvent, Z, flags, A, B, Call) {      \
  InstVfs *pInstVfs = (InstVfs *)pVfs;   \
  int rc;                                \
  sqlite3_int64 t = osinst_hwtime();     \
  rc = Call;                             \
  t = osinst_hwtime() - t;               \
  pInstVfs->aTime[eEvent] += t;          \
  pInstVfs->aCount[eEvent] += 1;         \
  if( pInstVfs->xCall ){                 \
    pInstVfs->xCall(pInstVfs->pClient,eEvent,0, t, rc, Z, flags, A, B); \
  }                                      \
  return rc;                             \
}







|
|
<
|
<

<
|
<
<
<
<
<
<
<
<





|

|













|

|







218
219
220
221
222
223
224
225
226

227

228

229








230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
  instUnlock,                     /* xUnlock */
  instCheckReservedLock,          /* xCheckReservedLock */
  instFileControl,                /* xFileControl */
  instSectorSize,                 /* xSectorSize */
  instDeviceCharacteristics       /* xDeviceCharacteristics */
};

/* 
** hwtime.h contains inline assembler code for implementing 

** high-performance timing routines.

*/

#include "hwtime.h"









#define OS_TIME_IO(eEvent, A, B, Call) {     \
  inst_file *p = (inst_file *)pFile;         \
  InstVfs *pInstVfs = p->pInstVfs;           \
  int rc;                                    \
  sqlite_uint64 t = sqlite3Hwtime();         \
  rc = Call;                                 \
  t = sqlite3Hwtime() - t;                   \
  pInstVfs->aTime[eEvent] += t;              \
  pInstVfs->aCount[eEvent] += 1;             \
  if( pInstVfs->xCall ){                     \
    pInstVfs->xCall(                         \
      pInstVfs->pClient,eEvent,p->iFileId,t,rc,p->zName,p->flags,A,B  \
    );                                       \
  }                                          \
  return rc;                                 \
}

#define OS_TIME_VFS(eEvent, Z, flags, A, B, Call) {      \
  InstVfs *pInstVfs = (InstVfs *)pVfs;   \
  int rc;                                \
  sqlite_uint64 t = sqlite3Hwtime();     \
  rc = Call;                             \
  t = sqlite3Hwtime() - t;               \
  pInstVfs->aTime[eEvent] += t;          \
  pInstVfs->aCount[eEvent] += 1;         \
  if( pInstVfs->xCall ){                 \
    pInstVfs->xCall(pInstVfs->pClient,eEvent,0, t, rc, Z, flags, A, B); \
  }                                      \
  return rc;                             \
}
Changes to src/vdbe.c.
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.743 2008/05/29 05:23:42 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor







|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.744 2008/05/29 20:22:37 shane Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
461
462
463
464
465
466
467

468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
#  define REGISTER_TRACE(R,M) if(p->trace&&R>0)registerTrace(p->trace,R,M)
#else
#  define REGISTER_TRACE(R,M)
#endif


#ifdef VDBE_PROFILE

/*
** 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__ unsigned long long int 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 (unsigned long long int)hi << 32 | lo;
}
#endif

/*
** The CHECK_FOR_INTERRUPT macro defined here looks to see if the
** sqlite3_interrupt() routine has been called.  If it has been, then
** processing of the VDBE program is interrupted.
**







>
|
<
|
|
<

|
<
<
<
<
|







461
462
463
464
465
466
467
468
469

470
471

472
473




474
475
476
477
478
479
480
481
#  define REGISTER_TRACE(R,M) if(p->trace&&R>0)registerTrace(p->trace,R,M)
#else
#  define REGISTER_TRACE(R,M)
#endif


#ifdef VDBE_PROFILE

/* 

** hwtime.h contains inline assembler code for implementing 
** high-performance timing routines.

*/
#include "hwtime.h"





#endif

/*
** The CHECK_FOR_INTERRUPT macro defined here looks to see if the
** sqlite3_interrupt() routine has been called.  If it has been, then
** processing of the VDBE program is interrupted.
**
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
  int rc = SQLITE_OK;        /* Value to return */
  sqlite3 *db = p->db;       /* The database */
  u8 encoding = ENC(db);     /* The database encoding */
  Mem *pIn1, *pIn2, *pIn3;   /* Input operands */
  Mem *pOut;                 /* Output operand */
  u8 opProperty;
#ifdef VDBE_PROFILE
  unsigned long long start;  /* CPU clock count at start of opcode */
  int origPc;                /* Program counter at start of opcode */
#endif
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  int nProgressOps = 0;      /* Opcodes executed since progress callback. */
#endif

  assert( p->magic==VDBE_MAGIC_RUN );  /* sqlite3_step() verifies this */







|







527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
  int rc = SQLITE_OK;        /* Value to return */
  sqlite3 *db = p->db;       /* The database */
  u8 encoding = ENC(db);     /* The database encoding */
  Mem *pIn1, *pIn2, *pIn3;   /* Input operands */
  Mem *pOut;                 /* Output operand */
  u8 opProperty;
#ifdef VDBE_PROFILE
  u64 start;                 /* CPU clock count at start of opcode */
  int origPc;                /* Program counter at start of opcode */
#endif
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  int nProgressOps = 0;      /* Opcodes executed since progress callback. */
#endif

  assert( p->magic==VDBE_MAGIC_RUN );  /* sqlite3_step() verifies this */
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
  sqlite3FaultEndBenign(-1);
#endif
  for(pc=p->pc; rc==SQLITE_OK; pc++){
    assert( pc>=0 && pc<p->nOp );
    if( db->mallocFailed ) goto no_mem;
#ifdef VDBE_PROFILE
    origPc = pc;
    start = hwtime();
#endif
    pOp = &p->aOp[pc];

    /* Only allow tracing if SQLITE_DEBUG is defined.
    */
#ifdef SQLITE_DEBUG
    if( p->trace ){







|







571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
  sqlite3FaultEndBenign(-1);
#endif
  for(pc=p->pc; rc==SQLITE_OK; pc++){
    assert( pc>=0 && pc<p->nOp );
    if( db->mallocFailed ) goto no_mem;
#ifdef VDBE_PROFILE
    origPc = pc;
    start = sqlite3Hwtime();
#endif
    pOp = &p->aOp[pc];

    /* Only allow tracing if SQLITE_DEBUG is defined.
    */
#ifdef SQLITE_DEBUG
    if( p->trace ){
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
** readability.  From this point on down, the normal indentation rules are
** restored.
*****************************************************************************/
    }

#ifdef VDBE_PROFILE
    {
      long long elapse = hwtime() - start;
      pOp->cycles += elapse;
      pOp->cnt++;
#if 0
        fprintf(stdout, "%10lld ", elapse);
        sqlite3VdbePrintOp(stdout, origPc, &p->aOp[origPc]);
#endif
    }
#endif

    /* The following code adds nothing to the actual functionality
    ** of the program.  It is only here for testing and debugging.







|
|


|







4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
** readability.  From this point on down, the normal indentation rules are
** restored.
*****************************************************************************/
    }

#ifdef VDBE_PROFILE
    {
      u64 elapsed = sqlite3Hwtime() - start;
      pOp->cycles += elapsed;
      pOp->cnt++;
#if 0
        fprintf(stdout, "%10llu ", elapsed);
        sqlite3VdbePrintOp(stdout, origPc, &p->aOp[origPc]);
#endif
    }
#endif

    /* The following code adds nothing to the actual functionality
    ** of the program.  It is only here for testing and debugging.
Changes to src/vdbe.h.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
*************************************************************************
** Header file for the Virtual DataBase Engine (VDBE)
**
** This header defines the interface to the virtual database engine
** or VDBE.  The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
** $Id: vdbe.h,v 1.131 2008/05/01 17:03:49 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines







|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
*************************************************************************
** Header file for the Virtual DataBase Engine (VDBE)
**
** This header defines the interface to the virtual database engine
** or VDBE.  The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
** $Id: vdbe.h,v 1.132 2008/05/29 20:22:37 shane Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
    VdbeFunc *pVdbeFunc;   /* Used when p4type is P4_VDBEFUNC */
    CollSeq *pColl;        /* Used when p4type is P4_COLLSEQ */
    Mem *pMem;             /* Used when p4type is P4_MEM */
    sqlite3_vtab *pVtab;   /* Used when p4type is P4_VTAB */
    KeyInfo *pKeyInfo;     /* Used when p4type is P4_KEYINFO */
  } p4;
#ifdef SQLITE_DEBUG
  char *zComment;     /* Comment to improve readability */
#endif
#ifdef VDBE_PROFILE
  int cnt;            /* Number of times this instruction was executed */
  long long cycles;   /* Total time spend executing this instruction */
#endif
};
typedef struct VdbeOp VdbeOp;

/*
** A smaller version of VdbeOp used for the VdbeAddOpList() function because
** it takes up less space.







|


|
|







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
    VdbeFunc *pVdbeFunc;   /* Used when p4type is P4_VDBEFUNC */
    CollSeq *pColl;        /* Used when p4type is P4_COLLSEQ */
    Mem *pMem;             /* Used when p4type is P4_MEM */
    sqlite3_vtab *pVtab;   /* Used when p4type is P4_VTAB */
    KeyInfo *pKeyInfo;     /* Used when p4type is P4_KEYINFO */
  } p4;
#ifdef SQLITE_DEBUG
  char *zComment;          /* Comment to improve readability */
#endif
#ifdef VDBE_PROFILE
  int cnt;                 /* Number of times this instruction was executed */
  u64 cycles;              /* Total time spent executing this instruction */
#endif
};
typedef struct VdbeOp VdbeOp;

/*
** A smaller version of VdbeOp used for the VdbeAddOpList() function because
** it takes up less space.
Changes to tool/mksqlite3c.tcl.
88
89
90
91
92
93
94

95
96
97
98
99
100
101
foreach hdr {
   btree.h
   btreeInt.h
   fts3.h
   fts3_hash.h
   fts3_tokenizer.h
   hash.h

   keywordhash.h
   mutex.h
   opcodes.h
   os_common.h
   os.h
   os_os2.h
   pager.h







>







88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
foreach hdr {
   btree.h
   btreeInt.h
   fts3.h
   fts3_hash.h
   fts3_tokenizer.h
   hash.h
   hwtime.h
   keywordhash.h
   mutex.h
   opcodes.h
   os_common.h
   os.h
   os_os2.h
   pager.h
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
  }
  set declpattern ^$declpattern
  while {![eof $in]} {
    set line [gets $in]
    if {[regexp {^#\s*include\s+["<]([^">]+)[">]} $line all hdr]} {
      if {[info exists available_hdr($hdr)]} {
        if {$available_hdr($hdr)} {
          if {$hdr!="os_common.h"} {
            set available_hdr($hdr) 0
          }
          section_comment "Include $hdr in the middle of $tail"
          copy_file tsrc/$hdr
          section_comment "Continuing where we left off in $tail"
        }
      } elseif {![info exists seen_hdr($hdr)]} {







|







143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
  }
  set declpattern ^$declpattern
  while {![eof $in]} {
    set line [gets $in]
    if {[regexp {^#\s*include\s+["<]([^">]+)[">]} $line all hdr]} {
      if {[info exists available_hdr($hdr)]} {
        if {$available_hdr($hdr)} {
          if {$hdr!="os_common.h" && $hdr!="hwtime.h"} {
            set available_hdr($hdr) 0
          }
          section_comment "Include $hdr in the middle of $tail"
          copy_file tsrc/$hdr
          section_comment "Continuing where we left off in $tail"
        }
      } elseif {![info exists seen_hdr($hdr)]} {
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
   os_os2.c
   os_unix.c
   os_win.c

   bitvec.c
   pager.c

   btmutex.c   
   btree.c

   vdbefifo.c
   vdbemem.c
   vdbeaux.c
   vdbeapi.c
   vdbe.c







|







226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
   os_os2.c
   os_unix.c
   os_win.c

   bitvec.c
   pager.c

   btmutex.c
   btree.c

   vdbefifo.c
   vdbemem.c
   vdbeaux.c
   vdbeapi.c
   vdbe.c
Changes to tool/mksqlite3internalh.tcl.
52
53
54
55
56
57
58

59
60
61
62
63
64
65
# files are seen in a #include statement in the C code, include the complete
# text of the file in-line.  The file only needs to be included once.
#
foreach hdr {
   btree.h
   btreeInt.h
   hash.h

   keywordhash.h
   opcodes.h
   os_common.h
   os.h
   os_os2.h
   pager.h
   parse.h







>







52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# files are seen in a #include statement in the C code, include the complete
# text of the file in-line.  The file only needs to be included once.
#
foreach hdr {
   btree.h
   btreeInt.h
   hash.h
   hwtime.h
   keywordhash.h
   opcodes.h
   os_common.h
   os.h
   os_os2.h
   pager.h
   parse.h
Changes to tool/speedtest16.c.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
** 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 speedtest16.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 database.db test.sql
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.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__ unsigned long long int 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 (unsigned long long int)hi << 32 | lo;
}

/*
** Convert a zero-terminated ASCII string into a zero-terminated
** UTF-16le string.  Memory to hold the returned string comes 
** from malloc() and should be freed by the caller.
*/
static void *asciiToUtf16le(const char *z){







|













<
|
<
<
>
|
<

|
<
<
<
<
<







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

32


33
34

35
36





37
38
39
40
41
42
43
** 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 speedtest16.c sqlite3.o -ldl -I../src
**
** 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 database.db test.sql
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include "sqlite3.h"


/* 


** hwtime.h contains inline assembler code for implementing 
** high-performance timing routines.

*/
#include "hwtime.h"






/*
** Convert a zero-terminated ASCII string into a zero-terminated
** UTF-16le string.  Memory to hold the returned string comes 
** from malloc() and should be freed by the caller.
*/
static void *asciiToUtf16le(const char *z){
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
  }
  return (void*)z16;
}

/*
** Timers
*/
static unsigned long long int prepTime = 0;
static unsigned long long int runTime = 0;
static unsigned long long int finalizeTime = 0;

/*
** Prepare and run a single statement of SQL.
*/
static void prepareAndRun(sqlite3 *db, const char *zSql){
  void *utf16;
  sqlite3_stmt *pStmt;
  const void *stmtTail;
  unsigned long long int iStart, iElapse;
  int rc;
  
  printf("****************************************************************\n");
  printf("SQL statement: [%s]\n", zSql);
  utf16 = asciiToUtf16le(zSql);
  iStart = hwtime();
  rc = sqlite3_prepare16_v2(db, utf16, -1, &pStmt, &stmtTail);
  iElapse = hwtime() - iStart;
  prepTime += iElapse;
  printf("sqlite3_prepare16_v2() returns %d in %llu cycles\n", rc, iElapse);
  if( rc==SQLITE_OK ){
    int nRow = 0;
    iStart = hwtime();
    while( (rc=sqlite3_step(pStmt))==SQLITE_ROW ){ nRow++; }
    iElapse = hwtime() - iStart;
    runTime += iElapse;
    printf("sqlite3_step() returns %d after %d rows in %llu cycles\n",
           rc, nRow, iElapse);
    iStart = hwtime();
    rc = sqlite3_finalize(pStmt);
    iElapse = hwtime() - iStart;
    finalizeTime += iElapse;
    printf("sqlite3_finalize() returns %d in %llu cycles\n", rc, iElapse);
  }
  free(utf16);
}

int main(int argc, char **argv){
  void *utf16;
  sqlite3 *db;
  int rc;
  int nSql;
  char *zSql;
  int i, j;
  FILE *in;
  unsigned long long int iStart, iElapse;
  unsigned long long int iSetup = 0;
  int nStmt = 0;
  int nByte = 0;

  if( argc!=3 ){
    fprintf(stderr, "Usage: %s FILENAME SQL-SCRIPT\n"
                    "Runs SQL-SCRIPT as UTF16 against a UTF16 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]);
  utf16 = asciiToUtf16le(argv[1]);
  iStart = hwtime();
  rc = sqlite3_open16(utf16, &db);
  iElapse = hwtime() - iStart;
  iSetup = iElapse;
  printf("sqlite3_open16() returns %d in %llu cycles\n", rc, iElapse);
  free(utf16);
  for(i=j=0; j<nSql; j++){
    if( zSql[j]==';' ){
      int isComplete;
      char c = zSql[j+1];







|
|
|








|





|

|




|

|



|

|














|
|




















|

|







52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
  }
  return (void*)z16;
}

/*
** Timers
*/
static sqlite_uint64 prepTime = 0;
static sqlite_uint64 runTime = 0;
static sqlite_uint64 finalizeTime = 0;

/*
** Prepare and run a single statement of SQL.
*/
static void prepareAndRun(sqlite3 *db, const char *zSql){
  void *utf16;
  sqlite3_stmt *pStmt;
  const void *stmtTail;
  sqlite_uint64 iStart, iElapse;
  int rc;
  
  printf("****************************************************************\n");
  printf("SQL statement: [%s]\n", zSql);
  utf16 = asciiToUtf16le(zSql);
  iStart = sqlite3Hwtime();
  rc = sqlite3_prepare16_v2(db, utf16, -1, &pStmt, &stmtTail);
  iElapse = sqlite3Hwtime() - iStart;
  prepTime += iElapse;
  printf("sqlite3_prepare16_v2() returns %d in %llu cycles\n", rc, iElapse);
  if( rc==SQLITE_OK ){
    int nRow = 0;
    iStart = sqlite3Hwtime();
    while( (rc=sqlite3_step(pStmt))==SQLITE_ROW ){ nRow++; }
    iElapse = sqlite3Hwtime() - iStart;
    runTime += iElapse;
    printf("sqlite3_step() returns %d after %d rows in %llu cycles\n",
           rc, nRow, iElapse);
    iStart = sqlite3Hwtime();
    rc = sqlite3_finalize(pStmt);
    iElapse = sqlite3Hwtime() - iStart;
    finalizeTime += iElapse;
    printf("sqlite3_finalize() returns %d in %llu cycles\n", rc, iElapse);
  }
  free(utf16);
}

int main(int argc, char **argv){
  void *utf16;
  sqlite3 *db;
  int rc;
  int nSql;
  char *zSql;
  int i, j;
  FILE *in;
  sqlite_uint64 iStart, iElapse;
  sqlite_uint64 iSetup = 0;
  int nStmt = 0;
  int nByte = 0;

  if( argc!=3 ){
    fprintf(stderr, "Usage: %s FILENAME SQL-SCRIPT\n"
                    "Runs SQL-SCRIPT as UTF16 against a UTF16 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]);
  utf16 = asciiToUtf16le(argv[1]);
  iStart = sqlite3Hwtime();
  rc = sqlite3_open16(utf16, &db);
  iElapse = sqlite3Hwtime() - iStart;
  iSetup = iElapse;
  printf("sqlite3_open16() returns %d in %llu cycles\n", rc, iElapse);
  free(utf16);
  for(i=j=0; j<nSql; j++){
    if( zSql[j]==';' ){
      int isComplete;
      char c = zSql[j+1];
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
          prepareAndRun(db, &zSql[i]);
        }
        zSql[j] = ';';
        i = j+1;
      }
    }
  }
  iStart = hwtime();
  sqlite3_close(db);
  iElapse = hwtime() - iStart;
  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;
}







|

|













147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
          prepareAndRun(db, &zSql[i]);
        }
        zSql[j] = ';';
        i = j+1;
      }
    }
  }
  iStart = sqlite3Hwtime();
  sqlite3_close(db);
  iElapse = sqlite3Hwtime() - iStart;
  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;
}
Changes to tool/speedtest8.c.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28




29
30
31

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
** 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 <sys/times.h>
#include <time.h>
#include <sched.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__ unsigned long long int 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 (unsigned long long int)hi << 32 | lo;
}

/*
** Timers
*/
static unsigned long long int prepTime = 0;
static unsigned long long int runTime = 0;
static unsigned long long int finalizeTime = 0;

/*
** Prepare and run a single statement of SQL.
*/
static void prepareAndRun(sqlite3 *db, const char *zSql, int bQuiet){
  sqlite3_stmt *pStmt;
  const char *stmtTail;
  unsigned long long int iStart, iElapse;
  int rc;
  
  if (!bQuiet){
    printf("***************************************************************\n");
  }
  if (!bQuiet) printf("SQL statement: [%s]\n", zSql);
  iStart = hwtime();
  rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &stmtTail);
  iElapse = hwtime() - iStart;
  prepTime += iElapse;
  if (!bQuiet){
    printf("sqlite3_prepare_v2() returns %d in %llu cycles\n", rc, iElapse);
  }
  if( rc==SQLITE_OK ){
    int nRow = 0;
    iStart = hwtime();
    while( (rc=sqlite3_step(pStmt))==SQLITE_ROW ){ nRow++; }
    iElapse = hwtime() - iStart;
    runTime += iElapse;
    if (!bQuiet){
      printf("sqlite3_step() returns %d after %d rows in %llu cycles\n",
             rc, nRow, iElapse);
    }
    iStart = hwtime();
    rc = sqlite3_finalize(pStmt);
    iElapse = hwtime() - iStart;
    finalizeTime += iElapse;
    if (!bQuiet){
      printf("sqlite3_finalize() returns %d in %llu cycles\n", rc, iElapse);
    }
  }
}








|










|
>
>
>
>
|
|

>



|
|
<
|
<

|
<
<
<
<
<




|
|
|







|






|

|






|

|





|

|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

42

43
44





45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
** 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 -I../src
**
** 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 <time.h>

#if defined(_MSC_VER)
#include <windows.h>
#else
#include <unistd.h>
#include <sys/times.h>
#include <sched.h>
#endif

#include "sqlite3.h"

/* 
** hwtime.h contains inline assembler code for implementing 

** high-performance timing routines.

*/
#include "hwtime.h"






/*
** Timers
*/
static sqlite_uint64 prepTime = 0;
static sqlite_uint64 runTime = 0;
static sqlite_uint64 finalizeTime = 0;

/*
** Prepare and run a single statement of SQL.
*/
static void prepareAndRun(sqlite3 *db, const char *zSql, int bQuiet){
  sqlite3_stmt *pStmt;
  const char *stmtTail;
  sqlite_uint64 iStart, iElapse;
  int rc;
  
  if (!bQuiet){
    printf("***************************************************************\n");
  }
  if (!bQuiet) printf("SQL statement: [%s]\n", zSql);
  iStart = sqlite3Hwtime();
  rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &stmtTail);
  iElapse = sqlite3Hwtime() - iStart;
  prepTime += iElapse;
  if (!bQuiet){
    printf("sqlite3_prepare_v2() returns %d in %llu cycles\n", rc, iElapse);
  }
  if( rc==SQLITE_OK ){
    int nRow = 0;
    iStart = sqlite3Hwtime();
    while( (rc=sqlite3_step(pStmt))==SQLITE_ROW ){ nRow++; }
    iElapse = sqlite3Hwtime() - iStart;
    runTime += iElapse;
    if (!bQuiet){
      printf("sqlite3_step() returns %d after %d rows in %llu cycles\n",
             rc, nRow, iElapse);
    }
    iStart = sqlite3Hwtime();
    rc = sqlite3_finalize(pStmt);
    iElapse = sqlite3Hwtime() - iStart;
    finalizeTime += iElapse;
    if (!bQuiet){
      printf("sqlite3_finalize() returns %d in %llu cycles\n", rc, iElapse);
    }
  }
}

178
179
180
181
182
183
184
185
186
187
188
189
190

191
192

193
194
195
196
197
198
199
int main(int argc, char **argv){
  sqlite3 *db;
  int rc;
  int nSql;
  char *zSql;
  int i, j;
  FILE *in;
  unsigned long long int iStart, iElapse;
  unsigned long long int iSetup = 0;
  int nStmt = 0;
  int nByte = 0;
  const char *zArgv0 = argv[0];
  int bQuiet = 0;

  struct tms tmsStart, tmsEnd;
  clock_t clkStart, clkEnd;


#ifdef HAVE_OSINST
  extern sqlite3_vfs *sqlite3_instvfs_binarylog(char *, char *, char *);
  extern void sqlite3_instvfs_destroy(sqlite3_vfs *);
  sqlite3_vfs *pVfs = 0;
#endif








|
|




>


>







176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
int main(int argc, char **argv){
  sqlite3 *db;
  int rc;
  int nSql;
  char *zSql;
  int i, j;
  FILE *in;
  sqlite_uint64 iStart, iElapse;
  sqlite_uint64 iSetup = 0;
  int nStmt = 0;
  int nByte = 0;
  const char *zArgv0 = argv[0];
  int bQuiet = 0;
#if !defined(_MSC_VER)
  struct tms tmsStart, tmsEnd;
  clock_t clkStart, clkEnd;
#endif

#ifdef HAVE_OSINST
  extern sqlite3_vfs *sqlite3_instvfs_binarylog(char *, char *, char *);
  extern void sqlite3_instvfs_destroy(sqlite3_vfs *);
  sqlite3_vfs *pVfs = 0;
#endif

219
220
221
222
223
224
225












226
227
228
229
230
231
232
233
234

235
236
237
238
239
240
241
    /*
    ** Increasing the priority slightly above normal can help with
    ** repeatability of testing.  Note that with Cygwin, -5 equates
    ** to "High", +5 equates to "Low", and anything in between
    ** equates to "Normal".
    */
    if( argc>4 && (strcmp(argv[1], "-priority")==0) ){












      struct sched_param myParam;
      sched_getparam(0, &myParam);
      printf ("Current process priority is %d.\n", (int)myParam.sched_priority); 
      myParam.sched_priority = atoi(argv[2]);
      printf ("Setting process priority to %d.\n", (int)myParam.sched_priority); 
      if (sched_setparam (0, &myParam) != 0){
        printf ("error setting priority\n"); 
        exit(2); 
      }

      argv += 2;
      argc -= 2;
      continue;
    }

    if( argc>3 && strcmp(argv[1], "-quiet")==0 ){
     bQuiet = -1;







>
>
>
>
>
>
>
>
>
>
>
>









>







219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
    /*
    ** Increasing the priority slightly above normal can help with
    ** repeatability of testing.  Note that with Cygwin, -5 equates
    ** to "High", +5 equates to "Low", and anything in between
    ** equates to "Normal".
    */
    if( argc>4 && (strcmp(argv[1], "-priority")==0) ){
#if defined(_MSC_VER)
      int new_priority = atoi(argv[2]);
      if(!SetPriorityClass(GetCurrentProcess(), 
        (new_priority<=-5) ? HIGH_PRIORITY_CLASS : 
        (new_priority<=0)  ? ABOVE_NORMAL_PRIORITY_CLASS : 
        (new_priority==0)  ? NORMAL_PRIORITY_CLASS : 
        (new_priority<5)   ? BELOW_NORMAL_PRIORITY_CLASS : 
        IDLE_PRIORITY_CLASS)){
        printf ("error setting priority\n"); 
        exit(2); 
      }
#else
      struct sched_param myParam;
      sched_getparam(0, &myParam);
      printf ("Current process priority is %d.\n", (int)myParam.sched_priority); 
      myParam.sched_priority = atoi(argv[2]);
      printf ("Setting process priority to %d.\n", (int)myParam.sched_priority); 
      if (sched_setparam (0, &myParam) != 0){
        printf ("error setting priority\n"); 
        exit(2); 
      }
#endif
      argv += 2;
      argc -= 2;
      continue;
    }

    if( argc>3 && strcmp(argv[1], "-quiet")==0 ){
     bQuiet = -1;
267
268
269
270
271
272
273

274

275
276
277
278
279
280
281
282
283
284
  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]);

  clkStart = times(&tmsStart);

  iStart = hwtime();
  rc = sqlite3_open(argv[1], &db);
  iElapse = hwtime() - iStart;
  iSetup = iElapse;
  if (!bQuiet) 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;







>

>
|

|







280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
  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]);
#if !defined(_MSC_VER)
  clkStart = times(&tmsStart);
#endif
  iStart = sqlite3Hwtime();
  rc = sqlite3_open(argv[1], &db);
  iElapse = sqlite3Hwtime() - iStart;
  iSetup = iElapse;
  if (!bQuiet) 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;
295
296
297
298
299
300
301
302
303
304

305

306
307
308
309
310
311
312
313
314
315
316
317
318

319
320
321
322

323
324
325
326
327
328
329
330
331
332
          prepareAndRun(db, &zSql[i], bQuiet);
        }
        zSql[j] = ';';
        i = j+1;
      }
    }
  }
  iStart = hwtime();
  sqlite3_close(db);
  iElapse = hwtime() - iStart;

  clkEnd = times(&tmsEnd);

  iSetup += iElapse;
  if (!bQuiet) printf("sqlite3_close() returns in %llu cycles\n", iElapse);

  printf("\n");
  printf("Statements run:        %15d stmts\n", nStmt);
  printf("Bytes of SQL text:     %15d bytes\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);


  printf("\n");
  printf("Total user CPU time:   %15.3g secs\n", (tmsEnd.tms_utime - tmsStart.tms_utime)/(double)CLOCKS_PER_SEC );
  printf("Total system CPU time: %15.3g secs\n", (tmsEnd.tms_stime - tmsStart.tms_stime)/(double)CLOCKS_PER_SEC );
  printf("Total real time:       %15.3g secs\n", (clkEnd -clkStart)/(double)CLOCKS_PER_SEC );


#ifdef HAVE_OSINST
  if( pVfs ){
    sqlite3_instvfs_destroy(pVfs);
    printf("vfs log written to %s\n", argv[0]);
  }
#endif

  return 0;
}







|

|
>

>













>




>










310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
          prepareAndRun(db, &zSql[i], bQuiet);
        }
        zSql[j] = ';';
        i = j+1;
      }
    }
  }
  iStart = sqlite3Hwtime();
  sqlite3_close(db);
  iElapse = sqlite3Hwtime() - iStart;
#if !defined(_MSC_VER)
  clkEnd = times(&tmsEnd);
#endif
  iSetup += iElapse;
  if (!bQuiet) printf("sqlite3_close() returns in %llu cycles\n", iElapse);

  printf("\n");
  printf("Statements run:        %15d stmts\n", nStmt);
  printf("Bytes of SQL text:     %15d bytes\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);

#if !defined(_MSC_VER)
  printf("\n");
  printf("Total user CPU time:   %15.3g secs\n", (tmsEnd.tms_utime - tmsStart.tms_utime)/(double)CLOCKS_PER_SEC );
  printf("Total system CPU time: %15.3g secs\n", (tmsEnd.tms_stime - tmsStart.tms_stime)/(double)CLOCKS_PER_SEC );
  printf("Total real time:       %15.3g secs\n", (clkEnd -clkStart)/(double)CLOCKS_PER_SEC );
#endif

#ifdef HAVE_OSINST
  if( pVfs ){
    sqlite3_instvfs_destroy(pVfs);
    printf("vfs log written to %s\n", argv[0]);
  }
#endif

  return 0;
}
Changes to tool/speedtest8inst1.c.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
** 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);







|














|
|
<
|
<

|
<
<
<
<
<







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

34

35
36





37
38
39
40
41
42
43
** 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 -I../src
**
** 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"

/* 
** hwtime.h contains inline assembler code for implementing 

** high-performance timing routines.

*/
#include "hwtime.h"






/*
** Send a message to the log file.
*/
static void logMessage(const char *zFormat, ...){
  va_list ap;
  va_start(ap, zFormat);
132
133
134
135
136
137
138

139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
  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){







>
|

|

|

|




|

|

|

|







125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
  instCheckReservedLock,          /* xCheckReservedLock */
  instFileControl,                /* xFileControl */
  instSectorSize,                 /* xSectorSize */
  instDeviceCharacteristics       /* xDeviceCharacteristics */
};

#define OS_TIME_IO(MESSAGE, A, B, CALL)      \
  int rc;                                    \
  sqlite_uint64 t1, t2;                      \
  inst_file *p = (inst_file*)pFile;          \
  t1 = sqlite3Hwtime();                      \
  rc = CALL;                                 \
  t2 = sqlite3Hwtime();                      \
  logMessage(MESSAGE, A, B, t2-t1);          \
  instTime += sqlite3Hwtime() - t2;          \
  return rc;

#define OS_TIME_VFS(MESSAGE, A, B, CALL)                 \
  int rc;                                                \
  sqlite_uint64 t1, t2;                                  \
  sqlite3_vfs *pRealVfs = (sqlite3_vfs*)pVfs->pAppData;  \
  t1 = sqlite3Hwtime();                                  \
  rc = CALL;                                             \
  t2 = sqlite3Hwtime();                                  \
  logMessage(MESSAGE, A, B, t2-t1);                      \
  instTime += sqlite3Hwtime() - t2;                      \
  return rc;


/*
** Close an inst-file.
*/
static int instClose(sqlite3_file *pFile){
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487

/*
** 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]);







|





|

|






|

|





|

|













|
|







427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481

/*
** Prepare and run a single statement of SQL.
*/
static void prepareAndRun(sqlite3 *db, const char *zSql){
  sqlite3_stmt *pStmt;
  const char *stmtTail;
  sqlite_uint64 iStart, iElapse;
  int rc;
  
  printf("****************************************************************\n");
  printf("SQL statement: [%s]\n", zSql);
  instTime = 0;
  iStart = sqlite3Hwtime();
  rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &stmtTail);
  iElapse = sqlite3Hwtime();
  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 = sqlite3Hwtime();
    while( (rc=sqlite3_step(pStmt))==SQLITE_ROW ){ nRow++; }
    iElapse = sqlite3Hwtime();
    iElapse -= iStart + instTime;
    runTime += iElapse;
    printf("sqlite3_step() returns %d after %d rows in %llu cycles\n",
           rc, nRow, iElapse);
    instTime = 0;
    iStart = sqlite3Hwtime();
    rc = sqlite3_finalize(pStmt);
    iElapse = sqlite3Hwtime();
    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;
  sqlite_uint64 iStart, iElapse;
  sqlite_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]);
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
  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];







|

|







489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
  nSql = fread(zSql, 1, nSql, in);
  zSql[nSql] = 0;

  printf("SQLite version: %d\n", sqlite3_libversion_number());
  unlink(argv[1]);
  setupInstrumentedVfs();
  instTime = 0;
  iStart = sqlite3Hwtime();
  rc = sqlite3_open(argv[1], &db);
  iElapse = sqlite3Hwtime();
  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];
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
        }
        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);







|

|







516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
        }
        zSql[j] = ';';
        i = j+1;
      }
    }
  }
  instTime = 0;
  iStart = sqlite3Hwtime();
  sqlite3_close(db);
  iElapse = sqlite3Hwtime();
  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);