mirror of
https://github.com/sqlite/sqlite.git
synced 2025-04-21 19:26:38 +03:00
305 lines
8.3 KiB
Tcl
Executable File
305 lines
8.3 KiB
Tcl
Executable File
#!/bin/sh
|
|
# the next line restarts using tclsh \
|
|
exec tclsh "$0" ${1+"$@"}
|
|
#
|
|
# This program runs performance testing on sqlite3.c. Usage:
|
|
set usage {USAGE:
|
|
|
|
speedtest.tcl sqlite3.c x1.txt trunk.txt -Os -DSQLITE_ENABLE_STAT4
|
|
| | | `-----------------------'
|
|
File to test ----' | | |
|
|
| | `- options
|
|
Output filename --------' |
|
|
`--- optional prior output to diff
|
|
|
|
Do a cache-grind performance analysis of the sqlite3.c file named and
|
|
write the results into the output file. The ".txt" is appended to the
|
|
output file (and diff-file) name if it is not already present. If the
|
|
diff-file is specified then show a diff from the diff-file to the new
|
|
output.
|
|
|
|
Other options include:
|
|
CC=... Specify an alternative C compiler. Default is "gcc".
|
|
-D... -D and -O options are passed through to the C compiler.
|
|
--dryrun Show what would happen but don't do anything.
|
|
--help Show this help screen.
|
|
--lean "Lean" mode.
|
|
--lookaside N SZ Lookahead uses N slots of SZ bytes each.
|
|
--pagesize N Use N as the page size.
|
|
--quiet | -q "Quite". Put results in file but don't pop up editor
|
|
--size N Change the test size. 100 means 100%. Default: 5.
|
|
--testset TEST Specify the specific testset to use. The default
|
|
is "mix1". Other options include: "main", "json",
|
|
"cte", "orm", "fp", "rtree".
|
|
}
|
|
set srcfile {}
|
|
set outfile {}
|
|
set difffile {}
|
|
set cflags {-DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_THREADSAFE=0}
|
|
set cc gcc
|
|
set testset mix1
|
|
set dryrun 0
|
|
set quiet 0
|
|
set speedtestflags {--shrink-memory --reprepare --stats --heap 40000000 64}
|
|
lappend speedtestflags --journal wal --size 5
|
|
|
|
for {set i 0} {$i<[llength $argv]} {incr i} {
|
|
set arg [lindex $argv $i]
|
|
if {[string index $arg 0]=="-"} {
|
|
switch -- $arg {
|
|
-pagesize -
|
|
--pagesize {
|
|
lappend speedtestflags --pagesize
|
|
incr i
|
|
lappend speedtestflags [lindex $argv $i]
|
|
}
|
|
-lookaside -
|
|
--lookaside {
|
|
lappend speedtestflags --lookaside
|
|
incr i
|
|
lappend speedtestflags [lindex $argv $i]
|
|
incr i
|
|
lappend speedtestflags [lindex $argv $i]
|
|
}
|
|
-lean -
|
|
--lean {
|
|
lappend cflags \
|
|
-DSQLITE_DEFAULT_MEMSTATUS=0 \
|
|
-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 \
|
|
-DSQLITE_LIKE_DOESNT_MATCH_BLOBS=1 \
|
|
-DSQLITE_MAX_EXPR_DEPTH=1 \
|
|
-DSQLITE_OMIT_DECLTYPE \
|
|
-DSQLITE_OMIT_DEPRECATED \
|
|
-DSQLITE_OMIT_PROGRESS_CALLBACK \
|
|
-DSQLITE_OMIT_SHARED_CACHE \
|
|
-DSQLITE_USE_ALLOCA
|
|
}
|
|
-testset -
|
|
--testset {
|
|
incr i
|
|
set testset [lindex $argv $i]
|
|
}
|
|
-size -
|
|
--size {
|
|
incr i
|
|
set newsize [lindex $argv $i]
|
|
if {$newsize<1} {set newsize 1}
|
|
set speedtestflags \
|
|
[regsub {.-size \d+} $speedtestflags "-size $newsize"]
|
|
}
|
|
-n -
|
|
-dryrun -
|
|
--dryrun {
|
|
set dryrun 1
|
|
}
|
|
-? -
|
|
-help -
|
|
--help {
|
|
puts $usage
|
|
exit 0
|
|
}
|
|
-q -
|
|
-quiet -
|
|
--quiet {
|
|
set quiet 1
|
|
}
|
|
default {
|
|
lappend cflags $arg
|
|
}
|
|
}
|
|
continue
|
|
}
|
|
if {[string match CC=* $arg]} {
|
|
set cc [lrange $arg 3 end]
|
|
continue
|
|
}
|
|
if {[string match *.c $arg]} {
|
|
if {$srcfile!=""} {
|
|
puts stderr "multiple source files: $srcfile $arg"
|
|
exit 1
|
|
}
|
|
set srcfile $arg
|
|
continue
|
|
}
|
|
if {[lsearch {main cte rtree orm fp json parsenumber mix1} $arg]>=0} {
|
|
set testset $arg
|
|
continue
|
|
}
|
|
if {$outfile==""} {
|
|
set outfile $arg
|
|
continue
|
|
}
|
|
if {$difffile==""} {
|
|
set difffile $arg
|
|
continue
|
|
}
|
|
puts stderr "unknown option: \"$arg\". Use --help for more info."
|
|
exit 1
|
|
}
|
|
if {[lsearch -glob $cflags -O*]<0} {
|
|
lappend cflags -Os
|
|
}
|
|
if {[lsearch -glob $cflags -DSQLITE_ENABLE_MEMSYS*]<0} {
|
|
lappend cflags -DSQLITE_ENABLE_MEMSYS5
|
|
}
|
|
if {[lsearch -glob $cflags -DSQLITE_ENABLE_RTREE*]<0} {
|
|
lappend cflags -DSQLITE_ENABLE_RTREE
|
|
}
|
|
if {$srcfile==""} {
|
|
puts stderr "no sqlite3.c source file specified"
|
|
exit 1
|
|
}
|
|
if {![file readable $srcfile]} {
|
|
puts stderr "source file \"$srcfile\" does not exist"
|
|
exit 1
|
|
}
|
|
if {$outfile==""} {
|
|
puts stderr "no output file specified"
|
|
exit 1
|
|
}
|
|
if {![string match *.* [file tail $outfile]]} {
|
|
append outfile .txt
|
|
}
|
|
if {$difffile!=""} {
|
|
if {![file exists $difffile]} {
|
|
if {[file exists $difffile.txt]} {
|
|
append difffile .txt
|
|
} else {
|
|
puts stderr "No such file: \"$difffile\""
|
|
exit 1
|
|
}
|
|
}
|
|
}
|
|
|
|
set cccmd [list $cc -g]
|
|
lappend cccmd -I[file dir $srcfile]
|
|
lappend cccmd {*}[lsort $cflags]
|
|
lappend cccmd [file dir $argv0]/speedtest1.c
|
|
lappend cccmd $srcfile
|
|
lappend cccmd -o speedtest1
|
|
puts $cccmd
|
|
if {!$dryrun} {
|
|
exec {*}$cccmd
|
|
}
|
|
lappend speedtestflags --testset $testset
|
|
set stcmd [list valgrind --tool=cachegrind ./speedtest1 {*}$speedtestflags]
|
|
lappend stcmd speedtest1.db
|
|
lappend stcmd >valgrind-out.txt 2>valgrind-err.txt
|
|
puts $stcmd
|
|
if {!$dryrun} {
|
|
foreach file {speedtest1.db speedtest1.db-journal speedtest1.db-wal
|
|
speedtest1.db-shm} {
|
|
if {[file exists $file]} {file delete $file}
|
|
}
|
|
exec {*}$stcmd
|
|
}
|
|
|
|
set maxmtime 0
|
|
set cgfile {}
|
|
foreach cgout [glob -nocomplain cachegrind.out.*] {
|
|
if {[file mtime $cgout]>$maxmtime} {
|
|
set cgfile $cgout
|
|
set maxmtime [file mtime $cgfile]
|
|
}
|
|
}
|
|
if {$cgfile==""} {
|
|
puts "no cachegrind output"
|
|
exit 1
|
|
}
|
|
|
|
############# Process the cachegrind.out.# file ##########################
|
|
set fd [open $outfile wb]
|
|
set in [open "|cg_annotate --show=Ir --auto=yes --context=40 $cgfile" r]
|
|
set dest !
|
|
set out(!) {}
|
|
set linenum 0
|
|
set cntlines 0 ;# true to remember cycle counts on each line
|
|
set seenSqlite3 0 ;# true if we have seen the sqlite3.c file
|
|
while {![eof $in]} {
|
|
set line [string map {\t { }} [gets $in]]
|
|
if {[regexp {^-- Auto-annotated source: (.*)} $line all name]} {
|
|
set dest $name
|
|
if {[string match */sqlite3.c $dest]} {
|
|
set cntlines 1
|
|
set seenSqlite3 1
|
|
} else {
|
|
set cntlines 0
|
|
}
|
|
} elseif {[regexp {^-- line (\d+) ------} $line all ln]} {
|
|
set line [lreplace $line 2 2 {#}]
|
|
set linenum [expr {$ln-1}]
|
|
} elseif {[regexp {^The following files chosen for } $line]} {
|
|
set dest !
|
|
}
|
|
append out($dest) $line\n
|
|
if {$cntlines} {
|
|
incr linenum
|
|
if {[regexp {^ *([0-9,]+) } $line all x]} {
|
|
set x [string map {, {}} $x]
|
|
set cycles($linenum) $x
|
|
}
|
|
}
|
|
}
|
|
foreach x [lsort [array names out]] {
|
|
puts $fd $out($x)
|
|
}
|
|
# If the sqlite3.c file has been seen, then output a summary of the
|
|
# cycle counts for each file that went into making up sqlite3.c
|
|
#
|
|
if {$seenSqlite3} {
|
|
close $in
|
|
set in [open sqlite3.c]
|
|
set linenum 0
|
|
set fn sqlite3.c
|
|
set pattern1 {^/\*+ Begin file ([^ ]+) \*}
|
|
set pattern2 {^/\*+ Continuing where we left off in ([^ ]+) \*}
|
|
while {![eof $in]} {
|
|
set line [gets $in]
|
|
incr linenum
|
|
if {[regexp $pattern1 $line all newfn]} {
|
|
set fn $newfn
|
|
} elseif {[regexp $pattern2 $line all newfn]} {
|
|
set fn $newfn
|
|
} elseif {[info exists cycles($linenum)]} {
|
|
incr fcycles($fn) $cycles($linenum)
|
|
}
|
|
}
|
|
close $in
|
|
puts $fd \
|
|
{**********************************************************************}
|
|
set lx {}
|
|
set sum 0
|
|
foreach {fn cnt} [array get fcycles] {
|
|
lappend lx [list $cnt $fn]
|
|
incr sum $cnt
|
|
}
|
|
puts $fd [format {%20s %14d %8.3f%%} TOTAL $sum 100]
|
|
foreach entry [lsort -index 0 -integer -decreasing $lx] {
|
|
foreach {cnt fn} $entry break
|
|
puts $fd [format {%20s %14d %8.3f%%} $fn $cnt [expr {$cnt*100.0/$sum}]]
|
|
}
|
|
}
|
|
puts $fd "Executable size:"
|
|
close $fd
|
|
exec size speedtest1 >>$outfile
|
|
#
|
|
# Processed cachegrind output should now be in the $outfile
|
|
#############################################################################
|
|
|
|
if {$quiet} {
|
|
# Skip this last part of popping up a GUI viewer
|
|
} elseif {$difffile!=""} {
|
|
set fossilcmd {fossil xdiff --tk -c 20}
|
|
lappend fossilcmd $difffile
|
|
lappend fossilcmd $outfile
|
|
lappend fossilcmd &
|
|
puts $fossilcmd
|
|
if {!$dryrun} {
|
|
exec {*}$fossilcmd
|
|
}
|
|
} else {
|
|
if {!$dryrun} {
|
|
exec open $outfile
|
|
}
|
|
}
|