Skip to content

Instantly share code, notes, and snippets.

@sebres
Last active February 27, 2024 15:31
Show Gist options
  • Save sebres/4da0d7679211122bb2fe4f0d2e80c908 to your computer and use it in GitHub Desktop.
Save sebres/4da0d7679211122bb2fe4f0d2e80c908 to your computer and use it in GitHub Desktop.
profiling of ::tcl::clock::add (for ticket e02798626dfbcd7b33db19e0fc3a9fb9fa0714f4)
# small & simple profiler for measurement with inject:
proc ::_prof_reset {} {
unset -nocomplain ::_prof_tms
}
proc ::_prof_times {} {
upvar ::_prof_tms ptm
set lst {}
foreach {n v} [lsort -stride 2 -index 1 -decreasing -real [array get ptm]] {
if {[regexp {,cnt$} $n]} continue
lappend lst $n [format %.3f [expr {double($v) / $ptm($n,cnt)}]]
}
return $lst
}
proc ::_profile {seg code} {
upvar ::_prof_tms ptm
set stm [clock microseconds]
catch { uplevel $code } ret opt
incr ptm($seg) [expr {[clock microseconds] - $stm}]
incr ptm($seg,cnt)
return {*}$opt $ret
}
# short init and warming-up (load clock, TZ, etc):
clock scan "1 month" -gmt 1
# injected version of 9.0 ::tcl::clock::add:
proc ::tcl::clock::add { clockval args } {
if { [llength $args] % 2 != 0 } {
set cmdName "clock add"
return -code error \
-errorcode [list CLOCK wrongNumArgs] \
"wrong \# args: should be\
\"$cmdName clockval ?number units?...\
?-gmt boolean? ?-locale LOCALE? ?-timezone ZONE?\""
}
if { [catch { expr {wide($clockval)} } result] } {
return -code error $result
}
_profile init {
set offsets {}
set gmt 0
set locale c
set timezone [GetSystemTimeZone]
foreach { a b } $args {
if { [string is integer -strict $a] } {
lappend offsets $a $b
} else {
switch -exact -- $a {
-g - -gm - -gmt {
set saw(-gmt) {}
set gmt $b
}
-l - -lo - -loc - -loca - -local - -locale {
set locale [string tolower $b]
}
-t - -ti - -tim - -time - -timez - -timezo - -timezon -
-timezone {
set saw(-timezone) {}
set timezone $b
}
default {
throw [list CLOCK badOption $a] \
"bad option \"$a\",\
must be -gmt, -locale or -timezone"
}
}
}
}
# Check options for validity
if { [info exists saw(-gmt)] && [info exists saw(-timezone)] } {
return -code error \
-errorcode [list CLOCK gmtWithTimezone] \
"cannot use -gmt and -timezone in same call"
}
if { [catch { expr { wide($clockval) } } result] } {
return -code error "expected integer but got \"$clockval\""
}
if { ![string is boolean -strict $gmt] } {
return -code error "expected boolean value but got \"$gmt\""
} elseif { $gmt } {
set timezone :GMT
}
}
_profile entloc {
EnterLocale $locale
}
_profile chngov {
set changeover [mc GREGORIAN_CHANGE_DATE]
}
_profile setup {
if {[catch {SetupTimeZone $timezone} retval opts]} {
dict unset opts -errorinfo
return -options $opts $retval
}
}
_profile calc {
try {
foreach { quantity unit } $offsets {
switch -exact -- $unit {
years - year {
set clockval [AddMonths [expr { 12 * $quantity }] \
$clockval $timezone $changeover]
}
months - month {
set clockval [AddMonths $quantity $clockval $timezone \
$changeover]
}
weeks - week {
set clockval [AddDays [expr { 7 * $quantity }] \
$clockval $timezone $changeover]
}
days - day {
set clockval [AddDays $quantity $clockval $timezone \
$changeover]
}
hours - hour {
set clockval [expr { 3600 * $quantity + $clockval }]
}
minutes - minute {
set clockval [expr { 60 * $quantity + $clockval }]
}
seconds - second {
set clockval [expr { $quantity + $clockval }]
}
default {
throw [list CLOCK badUnit $unit] \
"unknown unit \"$unit\", must be \
years, months, weeks, days, hours, minutes or seconds"
}
}
}
return $clockval
} trap CLOCK {result opts} {
# Conceal the innards of [clock] when it's an expected error
dict unset opts -errorinfo
return -options $opts $result
}
}
}
::_prof_reset
timerate { ::tcl::clock::add 1700000000 1 month -gmt 1 }
::_prof_times
::_prof_reset
timerate { ::tcl::clock::add 1700000000 -gmt 1 }
::_prof_times
% info tclversion
-9.0
+8.6
% ::_prof_reset
% timerate { ::tcl::clock::add 1700000000 1 month -gmt 1 }
-94.2670 µs/# 10609 # 10608.2 #/sec 1000.079 net-ms
+28.0587 µs/# 35640 # 35639.6 #/sec 1000.012 net-ms
% ::_prof_times
-entloc 33.018 chngov 29.982 calc 10.014 init 7.927 setup 2.144
+calc 6.492 init 5.831 chngov 3.010 entloc 2.523 setup 1.525
%
% ::_prof_reset
% timerate { ::tcl::clock::add 1700000000 -gmt 1 }
-81.8039 µs/# 12225 # 12224.4 #/sec 1000.053 net-ms
+22.1857 µs/# 45075 # 45074.1 #/sec 1000.020 net-ms
% ::_prof_times
-entloc 31.142 chngov 29.018 init 6.421 calc 2.677 setup 2.055
+init 5.011 chngov 2.909 entloc 2.444 calc 1.980 setup 1.499
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment