# tclbench.tcl — portable Tcl CPU/interpreter benchmark for native-vs-brintOS # comparison. Pure Tcl 8.5+; no packages; fixed workloads so scores are # comparable across hosts. Output: "BENCH " # plus a one-line SUMMARY. Total runtime target: ~5-20 s native, a few # minutes under wasm. # # Run: tclsh tclbench.tcl # Areas: proc-call overhead, integer/float arithmetic, string building, # list sort, dict churn, regexp, recursion, file I/O. proc bench {name iters body} { # warm once (bytecode compile), then measure uplevel 1 $body set us [lindex [uplevel 1 [list time $body $iters]] 0] puts [format "BENCH %-14s %12.2f us/iter" $name $us] return $us } puts "TCLBENCH v1 host=[info hostname] tcl=[info patchlevel] os=$tcl_platform(os) machine=$tcl_platform(machine)" puts "CLOCK resolution probe: [time {clock microseconds} 1000]" set total 0.0 # 1. integer arithmetic + loop overhead set total [expr {$total + [bench int-arith 20 { set s 0 for {set i 0} {$i < 100000} {incr i} { set s [expr {$s + $i*3 % 7}] } }]}] # 2. floating point set total [expr {$total + [bench float-math 20 { set s 0.0 for {set i 1} {$i < 20000} {incr i} { set s [expr {$s + sqrt($i) * 1.0001 / $i}] } }]}] # 3. proc-call overhead (function dispatch) proc add3 {a b c} { expr {$a + $b + $c} } set total [expr {$total + [bench proc-call 20 { set s 0 for {set i 0} {$i < 50000} {incr i} { set s [add3 $s 1 2] } }]}] # 4. string building (append; exercises memory/realloc) set total [expr {$total + [bench string-append 50 { set s "" for {set i 0} {$i < 5000} {incr i} { append s "x$i" } }]}] # 5. list build + sort set total [expr {$total + [bench list-sort 20 { set l {} for {set i 0} {$i < 5000} {incr i} { lappend l [expr {($i * 7919) % 5000}] } lsort -integer $l }]}] # 6. dict churn (hash table) set total [expr {$total + [bench dict-churn 20 { set d [dict create] for {set i 0} {$i < 5000} {incr i} { dict set d "k$i" $i } set s 0 for {set i 0} {$i < 5000} {incr i} { incr s [dict get $d "k$i"] } }]}] # 7. regexp engine set total [expr {$total + [bench regexp 20 { set hits 0 for {set i 0} {$i < 2000} {incr i} { if {[regexp {([a-z]+)([0-9]+)} "abc$i-def" -> w n]} { incr hits } } }]}] # 8. recursion (deep call stacks — interesting under the coro substrate) proc fib {n} { expr {$n < 2 ? $n : [fib [expr {$n-1}]] + [fib [expr {$n-2}]]} } set total [expr {$total + [bench recursion-fib18 10 { fib 18 }]}] # 9. file I/O (write+read 100 KB — exercises the fs path end-to-end) set total [expr {$total + [bench file-io-100k 10 { set f [open bench.tmp w]; puts -nonewline $f [string repeat "0123456789abcdef" 6400]; close $f set f [open bench.tmp r]; set data [read $f]; close $f }]}] catch {file delete bench.tmp} puts [format "SUMMARY total-score %.2f (sum us/iter; lower is faster)" $total]