Fixes default log output to console for macOS
[sqlcipher.git] / tool / crypto-speedtest.tcl
blobfa923a01020ee1aa9d8d2445c0cb6392a20ed0b9
1 #!/usr/bin/tclsh
3 # SQLite Cipher
4 # codec-speedtest.tcl developed by Stephen Lombardo (Zetetic LLC)
5 # sjlombardo at zetetic dot net
6 # http://zetetic.net
7 #
8 # Copyright (c) 2008, ZETETIC LLC
9 # All rights reserved.
11 # Redistribution and use in source and binary forms, with or without
12 # modification, are permitted provided that the following conditions are met:
13 # * Redistributions of source code must retain the above copyright
14 # notice, this list of conditions and the following disclaimer.
15 # * Redistributions in binary form must reproduce the above copyright
16 # notice, this list of conditions and the following disclaimer in the
17 # documentation and/or other materials provided with the distribution.
18 # * Neither the name of the ZETETIC LLC nor the
19 # names of its contributors may be used to endorse or promote products
20 # derived from this software without specific prior written permission.
22 # THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
23 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 # DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
26 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 # Run this script using TCLSH to do a speed comparison between
34 # a single version of sqlite running with and without the codec
35 # based heavily on tools/speetest.tcl in the standard SQLite package
38 # Run a test
40 set cnt 1
41 proc runtest {title} {
42 global cnt
43 set sqlfile test$cnt.sql
44 set logfile test$cnt.log
45 puts "<h2>Test $cnt: $title</h2>"
46 incr cnt
47 set fd [open $sqlfile r]
48 set sql [string trim [read $fd [file size $sqlfile]]]
49 close $fd
50 set sx [split $sql \n]
51 set n [llength $sx]
52 if {$n>8} {
53 set sql {}
54 for {set i 0} {$i<3} {incr i} {append sql [lindex $sx $i]<br>\n}
55 append sql "<i>... [expr {$n-6}] lines omitted</i><br>\n"
56 for {set i [expr {$n-3}]} {$i<$n} {incr i} {
57 append sql [lindex $sx $i]<br>\n
59 } else {
60 regsub -all \n [string trim $sql] <br> sql
62 puts "<blockquote>"
63 puts "$sql"
64 puts "</blockquote><table border=0 cellpadding=0 cellspacing=0>"
65 set format {<tr><td>%s</td><td align="right">&nbsp;&nbsp;&nbsp;%.3f</td></tr>}
66 set delay 10
68 exec sync; after $delay;
69 set t [time "exec cat perftest0.sql $sqlfile | ./sqlite3 perftest0.db 2>&1" 1]
70 set t [expr {[lindex $t 0]/1000000.0}]
71 puts [format $format {Config0:} $t]
72 exec sync; after $delay;
74 set t0 $t;
76 set t [time "exec cat perftest1.sql $sqlfile | ./sqlite3 perftest1.db 2>&1" 1]
77 set t [expr {[lindex $t 0]/1000000.0}]
78 puts [format $format {Config1:} $t]
79 exec sync; after $delay;
81 set slowdown [expr {(($t - $t0)/$t0)*100.0}]
82 puts [format $format {Slowdown:} $slowdown]
84 puts "</table>"
87 # Initialize the environment
90 file delete perftest0.db
91 file delete perftest1.db
93 expr srand(1)
94 catch {exec /bin/sh -c {rm -f perftest*.db}}
96 set fd [open perftest0.sql w]
97 puts $fd {
99 close $fd
101 set fd [open perftest1.sql w]
102 puts $fd {
103 PRAGMA key='xyzzy';
105 close $fd
107 exec cat perftest0.sql | ./sqlite3 perftest0.db
108 exec cat perftest1.sql | ./sqlite3 perftest1.db
110 set ones {zero one two three four five six seven eight nine
111 ten eleven twelve thirteen fourteen fifteen sixteen seventeen
112 eighteen nineteen}
113 set tens {{} ten twenty thirty forty fifty sixty seventy eighty ninety}
114 proc number_name {n} {
115 if {$n>=1000} {
116 set txt "[number_name [expr {$n/1000}]] thousand"
117 set n [expr {$n%1000}]
118 } else {
119 set txt {}
121 if {$n>=100} {
122 append txt " [lindex $::ones [expr {$n/100}]] hundred"
123 set n [expr {$n%100}]
125 if {$n>=20} {
126 append txt " [lindex $::tens [expr {$n/10}]]"
127 set n [expr {$n%10}]
129 if {$n>0} {
130 append txt " [lindex $::ones $n]"
132 set txt [string trim $txt]
133 if {$txt==""} {set txt zero}
134 return $txt
139 set fd [open test$cnt.sql w]
140 puts $fd "CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100));"
141 for {set i 1} {$i<=1000} {incr i} {
142 set r [expr {int(rand()*100000)}]
143 puts $fd "INSERT INTO t1 VALUES($i,$r,'[number_name $r]');"
145 close $fd
146 runtest {1000 INSERTs}
150 set fd [open test$cnt.sql w]
151 puts $fd "BEGIN;"
152 puts $fd "CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100));"
153 for {set i 1} {$i<=25000} {incr i} {
154 set r [expr {int(rand()*500000)}]
155 puts $fd "INSERT INTO t2 VALUES($i,$r,'[number_name $r]');"
157 puts $fd "COMMIT;"
158 close $fd
159 runtest {25000 INSERTs in a transaction}
163 set fd [open test$cnt.sql w]
164 for {set i 0} {$i<100} {incr i} {
165 set lwr [expr {$i*100}]
166 set upr [expr {($i+10)*100}]
167 puts $fd "SELECT count(*), avg(b) FROM t2 WHERE b>=$lwr AND b<$upr;"
169 close $fd
170 runtest {100 SELECTs without an index}
174 set fd [open test$cnt.sql w]
175 for {set i 1} {$i<=100} {incr i} {
176 puts $fd "SELECT count(*), avg(b) FROM t2 WHERE c LIKE '%[number_name $i]%';"
178 close $fd
179 runtest {100 SELECTs on a string comparison}
183 set fd [open test$cnt.sql w]
184 puts $fd {CREATE INDEX i2a ON t2(a);}
185 puts $fd {CREATE INDEX i2b ON t2(b);}
186 close $fd
187 runtest {Creating an index}
191 set fd [open test$cnt.sql w]
192 for {set i 0} {$i<5000} {incr i} {
193 set lwr [expr {$i*100}]
194 set upr [expr {($i+1)*100}]
195 puts $fd "SELECT count(*), avg(b) FROM t2 WHERE b>=$lwr AND b<$upr;"
197 close $fd
198 runtest {5000 SELECTs with an index}
202 set fd [open test$cnt.sql w]
203 puts $fd "BEGIN;"
204 for {set i 0} {$i<1000} {incr i} {
205 set lwr [expr {$i*10}]
206 set upr [expr {($i+1)*10}]
207 puts $fd "UPDATE t1 SET b=b*2 WHERE a>=$lwr AND a<$upr;"
209 puts $fd "COMMIT;"
210 close $fd
211 runtest {1000 UPDATEs without an index}
215 set fd [open test$cnt.sql w]
216 puts $fd "BEGIN;"
217 for {set i 1} {$i<=25000} {incr i} {
218 set r [expr {int(rand()*500000)}]
219 puts $fd "UPDATE t2 SET b=$r WHERE a=$i;"
221 puts $fd "COMMIT;"
222 close $fd
223 runtest {25000 UPDATEs with an index}
226 set fd [open test$cnt.sql w]
227 puts $fd "BEGIN;"
228 for {set i 1} {$i<=25000} {incr i} {
229 set r [expr {int(rand()*500000)}]
230 puts $fd "UPDATE t2 SET c='[number_name $r]' WHERE a=$i;"
232 puts $fd "COMMIT;"
233 close $fd
234 runtest {25000 text UPDATEs with an index}
238 set fd [open test$cnt.sql w]
239 puts $fd "BEGIN;"
240 puts $fd "INSERT INTO t1 SELECT * FROM t2;"
241 puts $fd "INSERT INTO t2 SELECT * FROM t1;"
242 puts $fd "COMMIT;"
243 close $fd
244 runtest {INSERTs from a SELECT}
248 set fd [open test$cnt.sql w]
249 puts $fd {DELETE FROM t2 WHERE c LIKE '%fifty%';}
250 close $fd
251 runtest {DELETE without an index}
255 set fd [open test$cnt.sql w]
256 puts $fd {DELETE FROM t2 WHERE a>10 AND a<20000;}
257 close $fd
258 runtest {DELETE with an index}
262 set fd [open test$cnt.sql w]
263 puts $fd {INSERT INTO t2 SELECT * FROM t1;}
264 close $fd
265 runtest {A big INSERT after a big DELETE}
269 set fd [open test$cnt.sql w]
270 puts $fd {BEGIN;}
271 puts $fd {DELETE FROM t1;}
272 for {set i 1} {$i<=3000} {incr i} {
273 set r [expr {int(rand()*100000)}]
274 puts $fd "INSERT INTO t1 VALUES($i,$r,'[number_name $r]');"
276 puts $fd {COMMIT;}
277 close $fd
278 runtest {A big DELETE followed by many small INSERTs}
282 set fd [open test$cnt.sql w]
283 puts $fd {DROP TABLE t1;}
284 puts $fd {DROP TABLE t2;}
285 close $fd
286 runtest {DROP TABLE}