[MS] 2008-03-04 NRE is the nickname for '''Non-recursive Engine''', an experimental new implementation of Tcl at [http://tcl.msofer.com:8080/wiki?name=NRE]. It was announced at [http://aspn.activestate.com/ASPN/Mail/Message/tcl-core/3612000], a short clumsy description is at [http://tcl.msofer.com:8080/wiki?name=NRE+short+explanation]. See also [NRE: the non-recursive engine in Tcl 8.6]. The initial problem NRE is called to solve is Tcl's hungriness for C stack resources, which preempt deep recursion. NRE reduces the C stack consumption very noticeably, essentially making the recursion limit infinite (recursion depth is bound by the heap not the stack). It also provides an experimental implementation for proper tailcalls - ie, making the recursion depth bound by the electricity supply and/or the lifetime of the hardware. Exciting further developments are planned, mostly with respect to [concurrency concepts]. NRE's first implementation lives in the mod-core-8-3-4 branch in the tcl.sf.net's CVS. The new and ''much'' improved can be downloaded from [http://tcl.msofer.com:8080], a specific wiki is also maintained there. [DKF] 2008–07–13: NRE is now in the CVS HEAD and will therefore form part of the 8.6a2 release. [stevel] 2008-07-16: Tclkits (i.e. single-file executables) containing Tcl 8.6a1 and NRE are now available to facilitate testing * Windows - http://www.tcl.tk/starkits/nrekit.exe and http://www.tcl.tk/starkits/nrekitsh.exe * OSX (universal) - http://www.tcl.tk/starkits/nrekit-osx-universal.gz * Linux (ix86) - http://www.tcl.tk/starkits/nrekit-linux-ix86.gz [MS] 2008-08-07 NRE includes two new commands in [::tcl::unsupported::tailcall] and [atProcExit], which will probably be [TIP]ped before release. Not much docs, initial examples in ''tests/unsupported.test''. More goodies in the works ... ---- **Demonstration** Showing off - on a 256kB stack (128kB crashes on startup): mig@uh:/home/CVS/fossil/tcl/unix$ ulimit -s 256 mig@uh:/home/CVS/fossil/tcl/unix$ ulimit -S 256 mig@uh:/home/CVS/fossil/tcl/unix$ ./tclsh % proc a i {if {[incr i] > 50000} {return $i}; a $i} % a 0 too many nested evaluations (infinite loop?) % interp recursionlimit {} 10000000 10000000 % a 0 50001 ---- **Performance** ''JH 2010-10-17: The numbers below are not substantiated or reproducible by anyone. Attribution is uncertain. Pat Thoyts did a similar clean benchmark run (results [http://www.patthoyts.tk/bench/20080723-odr.txt]) that indicates NRE had a 5% overall, but 15-20% impact on performance oriented (non-IO/algorithmic) tests.'' What about speed? To get an impression, I compared tcl cvs head and tcl NRE from 2008-03-04, both compiled just with ./configure (default optimization). Overall, tclNRE win. It seems, that tclNRE is often slightly slower, but for a few tests, it wins big. TCL_INTERP: 1:8.5.2b1 2:8.5.2b1 STARTED 2008-03-04 23:23:41 (runbench.tcl v1.21) Benchmark 1:8.5.2b1 /usr/local/tcl-nre-speed/bin/tclsh8.5 abbccdeeeffghkllmmmmnpprrssstuvw 00:02:01 elapsed Benchmark 2:8.5.2b1 /usr/local/tcl-head-speed/bin/tclsh8.5 abbccdeeeffghkllmmmmnpprrssstuvw 00:02:21 elapsed 000 VERSIONS: 1:8.5.2b1 2:8.5.2b1 001 ARRAY genKeys 50 268.39 264.03 002 ARRAY genKeys 500 2556.86 2479.40 003 ARRAY makeHash 500 50 57085.38 56991.14 004 BASE64 decode 10 80.83 82.30 005 BASE64 decode 100 607.45 578.80 006 BASE64 decode 1000 5954.75 5728.25 007 BASE64 decode 10000 58787.80 103005.3 008 BASE64 decode2 10 84.76 74.16 009 BASE64 decode2 100 606.40 590.50 010 BASE64 decode2 1000 5729.20 5519.30 011 BASE64 decode2 10000 57363.40 132742.6 012 BASE64 decode3 10 44.01 42.53 013 BASE64 decode3 100 307.20 286.00 014 BASE64 decode3 1000 2881.75 2738.40 015 BASE64 decode3 10000 29059.10 65912.10 016 BASE64 encode 10 63.24 62.94 017 BASE64 encode 100 515.85 486.27 018 BASE64 encode 1000 5031.50 4773.75 019 BASE64 encode 10000 49719.90 47591.50 020 BASE64 encode2 10 46.53 40.00 021 BASE64 encode2 100 356.77 312.75 022 BASE64 encode2 1000 3343.10 3004.10 023 BASE64 encode2 10000 33407.50 29449.40 024 BASE64 encode3 10 33.49 34.07 025 BASE64 encode3 100 133.93 136.12 026 BASE64 encode3 1000 1102.95 1133.15 027 BASE64 encode3 10000 10995.60 11295.10 028 BIN bitset-v1 1000 chars 3830.06 3531.66 029 BIN bitset-v1 5000 chars 18223.34 30303.85 030 BIN bitset-v1 10000 chars 35986.62 63433.68 031 BIN bitset-v2 1000 chars 2281.68 2049.22 032 BIN bitset-v2 5000 chars 11147.60 9889.81 033 BIN bitset-v2 10000 chars 22081.17 20221.75 034 BIN bitset-v3 1000 chars 680.61 674.55 035 BIN bitset-v3 5000 chars 3141.66 3081.54 036 BIN bitset-v3 10000 chars 6934.07 6812.02 037 BIN c scan, 1000b 201.42 197.39 038 BIN c scan, 5000b 692.15 678.93 039 BIN c scan, 10000b 1310.62 1291.72 040 BIN chars, 10000b 6929.07 6797.41 041 BIN u char, 10000b 1517.84 1494.45 042 CATCH error, complex 15.80 13.84 043 CATCH no catch used 4.89 4.33 044 CATCH return error 16.31 13.85 045 CATCH return except 5.24 4.12 046 CATCH return ok 5.36 4.91 047 DATA access in a list 131.35 127.82 048 DATA access in an array 599.33 602.05 049 DATA create in a list 165.04 159.72 050 DATA create in an array 799.66 786.07 051 ENC iso2022-jp, gets 138.43 135.73 052 ENC iso2022-jp, read 109.53 106.93 053 ENC iso2022-jp, read & size 118.87 113.23 054 ENC iso8859-2, gets 119.60 118.23 055 ENC iso8859-2, read 96.87 102.57 056 ENC iso8859-2, read & size 127.30 103.03 057 EVAL cmd and mixed lists 505.88 511.70 058 EVAL cmd eval as list 3.21 2.81 059 EVAL cmd eval as string 7.21 7.56 060 EVAL cmd eval in list obj var 3.29 2.94 061 EVAL list cmd and mixed lists 507.68 508.97 062 EVAL list cmd and pure lists 53.24 55.14 063 EXPR $a != $b int 1.73 1.57 064 EXPR $a != $b str (!= len) 3.77 3.76 065 EXPR $a != $b str (== len) 3.79 3.89 066 EXPR $a == $b int 1.73 2.27 067 EXPR $a == $b str (!= len) 3.96 3.70 068 EXPR $a == $b str (== len) 4.64 3.74 069 EXPR braced 5.50 4.56 070 EXPR fifty operands 5.21 5.47 071 EXPR incr with expr 1.49 1.37 072 EXPR incr with incr 1.27 1.13 073 EXPR inline 6.10 5.41 074 EXPR one operand 1.34 1.16 075 EXPR ten operands 2.10 2.01 076 EXPR unbraced 42.85 40.61 077 EXPR unbraced long 103.53 102.38 078 FCOPY binary: 160K 2810.39 2915.54 079 FCOPY encoding: 160K 5536.89 5547.08 080 FCOPY std: 160K 2821.04 2811.27 081 FILE exec interp 6187.87 6238.97 082 FILE exec interp: pkg require 16939.67 17254.63 083 FILE exists tmpfile (obj) 4.16 3.74 084 FILE exists ~ 2.72 2.72 085 FILE exists! tmpfile (obj) 3.07 2.96 086 FILE exists! tmpfile (str) 7.27 8.96 087 FILE glob tmpdir (60 entries) 106.14 115.61 088 FILE glob / all subcommands 9391.12 11242.17 089 FILE glob / atime 805.16 770.31 090 FILE glob / attributes 5794.90 13841.92 091 FILE glob / dirname 155.37 153.72 092 FILE glob / executable 808.62 765.00 093 FILE glob / exists 806.89 758.39 094 FILE glob / extension 184.65 172.71 095 FILE glob / isdirectory 802.42 770.53 096 FILE glob / isfile 801.31 1856.42 097 FILE glob / mtime 802.94 1827.71 098 FILE glob / owned 816.73 1884.02 099 FILE glob / readable 800.29 1849.52 100 FILE glob / rootname 205.63 468.79 101 FILE glob / size 805.67 1873.71 102 FILE glob / tail 155.65 380.19 103 FILE glob / writable 808.97 1830.76 104 FILE recurse / -dir 3598.89 3515.68 105 FILE recurse / cd 3651.62 3531.71 106 GCCont_cpb::cGCC 50 73.54 72.95 107 GCCont_cpb::cGCC 500 425.15 438.72 108 GCCont_cpb::cGCC 5000 3903.84 9373.96 109 GCCont_cpbre1::cGCC 50 96.59 90.81 110 GCCont_cpbre1::cGCC 500 614.77 605.80 111 GCCont_cpbre1::cGCC 5000 5756.60 5731.70 112 GCCont_cpbre2::cGCC 50 75.05 71.24 113 GCCont_cpbre2::cGCC 500 546.87 538.89 114 GCCont_cpbre2::cGCC 5000 5256.78 5225.72 115 GCCont_cpbrs2::cGCC 50 28.21 26.29 116 GCCont_cpbrs2::cGCC 500 119.82 117.01 117 GCCont_cpbrs2::cGCC 5000 1014.48 1008.78 118 GCCont_cpbrs::cGCC1 50 49.44 46.44 119 GCCont_cpbrs::cGCC1 500 151.78 144.81 120 GCCont_cpbrs::cGCC1 5000 1115.96 2646.38 121 GCCont_cpbrs::cGCC2 50 43.68 42.33 122 GCCont_cpbrs::cGCC2 500 131.85 130.39 123 GCCont_cpbrs::cGCC2 5000 1028.94 2361.30 124 GCCont_cpbrs_trap::cGCC 50 84.86 82.29 125 GCCont_cpbrs_trap::cGCC 500 580.87 582.16 126 GCCont_cpbrs_trap::cGCC 5000 5535.34 13290.76 127 GCCont_expr::cGCC 50 59.44 58.22 128 GCCont_expr::cGCC 500 324.23 320.14 129 GCCont_expr::cGCC 5000 3225.80 3376.22 130 GCCont_i::cGCC1 50 50.83 50.02 131 GCCont_i::cGCC1 500 424.24 416.91 132 GCCont_i::cGCC1 5000 4133.44 9659.00 133 GCCont_i::cGCC2 50 46.53 45.76 134 GCCont_i::cGCC2 500 378.24 374.42 135 GCCont_i::cGCC2 5000 3701.06 8622.28 136 GCCont_i::cGCC3 50 38.93 37.15 137 GCCont_i::cGCC3 500 292.98 285.69 138 GCCont_i::cGCC3 5000 2841.40 6529.74 139 GCCont_r1::cGCC 50 62.86 56.92 140 GCCont_r1::cGCC 500 576.85 541.99 141 GCCont_r1::cGCC 5000 5787.14 5243.34 142 GCCont_r2::cGCC 50 52.98 51.91 143 GCCont_r2::cGCC 500 453.73 441.10 144 GCCont_r2::cGCC 5000 4418.22 4354.44 145 GCCont_r3::cGCC 50 55.91 53.96 146 GCCont_r3::cGCC 500 470.89 464.49 147 GCCont_r3::cGCC 5000 4563.44 8070.34 148 GCCont_rsf1::cGCC 50 55.89 52.21 149 GCCont_rsf1::cGCC 500 363.04 353.40 150 GCCont_rsf1::cGCC 5000 3417.50 7976.76 151 GCCont_rsf2::cGCC1 50 37.74 34.64 152 GCCont_rsf2::cGCC1 500 196.96 190.06 153 GCCont_rsf2::cGCC1 5000 1770.86 4102.58 154 GCCont_rsf2::cGCC2 50 32.89 29.70 155 GCCont_rsf2::cGCC2 500 188.06 179.92 156 GCCont_rsf2::cGCC2 5000 1714.64 3984.60 157 GCCont_rsf3::cGCC 50 32.61 31.12 158 GCCont_rsf3::cGCC 500 187.77 181.29 159 GCCont_rsf3::cGCC 5000 1714.16 3856.40 160 GCCont_turing::cGCC 50 24.36 22.46 161 GCCont_turing::cGCC 500 115.43 111.25 162 GCCont_turing::cGCC 5000 1020.90 989.38 163 HEAPSORT size 10 111.73 115.05 164 HEAPSORT size 50 1015.81 1018.71 165 HEAPSORT size 100 2446.52 2463.86 166 HEAPSORT2 size 10 57.14 55.65 167 HEAPSORT2 size 50 460.88 459.26 168 HEAPSORT2 size 100 1102.31 1089.46 169 IF 1/0 check 1.41 1.28 170 IF else true al 2.99 2.85 171 IF else true numeric 2.24 1.96 172 IF elseif true al 3.30 3.06 173 IF elseif true numeric 2.03 2.08 174 IF if false al/al 2.36 2.15 175 IF if false al/num 2.39 2.18 176 IF if false num/num 1.84 1.70 177 IF if true al 2.30 2.12 178 IF if true al/al 2.44 2.36 179 IF if true num/num 1.86 1.71 180 IF if true numeric 1.79 1.67 181 IF multi 1st true 1.82 1.79 182 IF multi 2nd true 1.93 1.93 183 IF multi 9th true 2.91 3.07 184 IF multi default true 3.58 3.54 185 KLIST shuffle0 llength 1 12.03 9.56 186 KLIST shuffle0 llength 10 31.59 29.96 187 KLIST shuffle0 llength 100 241.18 218.68 188 KLIST shuffle0 llength 1000 2561.40 2337.20 189 KLIST shuffle0 llength 10000 52273.20 52327.80 190 KLIST shuffle1-s llength 1 6.86 9.60 191 KLIST shuffle1-s llength 10 49.71 43.46 192 KLIST shuffle1-s llength 100 668.20 627.08 193 KLIST shuffle1-s llength 1000 21294.60 39023.67 194 KLIST shuffle1a llength 1 9.43 26.69 195 KLIST shuffle1a llength 10 64.12 137.48 196 KLIST shuffle1a llength 100 625.15 1307.92 197 KLIST shuffle1a llength 1000 6260.57 11679.23 198 KLIST shuffle1a llength 10000 63778.90 57845.70 199 KLIST shuffle2 llength 1 11.14 11.77 200 KLIST shuffle2 llength 10 87.83 80.61 201 KLIST shuffle2 llength 100 861.11 799.38 202 KLIST shuffle2 llength 1000 8968.33 8271.55 203 KLIST shuffle2 llength 10000 114189.6 111530.3 204 KLIST shuffle3 llength 1 7.41 9.65 205 KLIST shuffle3 llength 10 48.93 43.40 206 KLIST shuffle3 llength 100 463.71 412.72 207 KLIST shuffle3 llength 1000 4739.29 4292.78 208 KLIST shuffle3 llength 10000 67351.50 63987.40 209 KLIST shuffle4 llength 1 7.45 8.91 210 KLIST shuffle4 llength 10 50.09 46.23 211 KLIST shuffle4 llength 100 460.52 424.15 212 KLIST shuffle4 llength 1000 4616.89 4205.85 213 KLIST shuffle4 llength 10000 47581.00 45389.00 214 KLIST shuffle5-s llength 1 5.96 5.02 215 KLIST shuffle5-s llength 10 40.55 32.59 216 KLIST shuffle5-s llength 100 450.02 371.67 217 KLIST shuffle5-s llength 1000 8233.00 9302.82 218 KLIST shuffle5a llength 1 7.21 5.78 219 KLIST shuffle5a llength 10 48.97 40.01 220 KLIST shuffle5a llength 100 464.08 374.32 221 KLIST shuffle5a llength 1000 4730.71 3867.87 222 KLIST shuffle5a llength 10000 66777.50 139490.1 223 KLIST shuffle6 llength 1 2.10 4.20 224 KLIST shuffle6 llength 10 22.09 46.78 225 KLIST shuffle6 llength 100 210.15 427.52 226 KLIST shuffle6 llength 1000 2125.62 4319.75 227 KLIST shuffle6 llength 10000 22624.80 50686.40 228 LIST append to list 2.77 4.85 229 LIST concat APPEND 2x10 11.36 10.66 230 LIST concat APPEND 2x100 74.08 79.20 231 LIST concat APPEND 2x1000 711.27 710.68 232 LIST concat APPEND 2x10000 9757.94 9620.99 233 LIST concat CONCAT 2x10 7.50 3.73 234 LIST concat CONCAT 2x100 5.58 5.39 235 LIST concat CONCAT 2x1000 21.96 21.18 236 LIST concat CONCAT 2x10000 421.24 417.18 237 LIST concat EVAL/LAPPEND 2x10 6.79 6.25 238 LIST concat EVAL/LAPPEND 2x100 11.53 10.93 239 LIST concat EVAL/LAPPEND 2x1000 55.91 55.11 240 LIST concat EVAL/LAPPEND 2x10000 770.69 773.80 241 LIST concat FOREACH/LAPPEND 2x10 7.45 16.66 242 LIST concat FOREACH/LAPPEND 2x100 42.04 97.86 243 LIST concat FOREACH/LAPPEND 2x1000 345.47 839.29 244 LIST concat FOREACH/LAPPEND 2x10000 3698.54 7157.24 245 LIST concat SET 2x10 9.69 8.73 246 LIST concat SET 2x100 69.69 67.18 247 LIST concat SET 2x1000 645.86 649.66 248 LIST concat SET 2x10000 9064.59 8885.44 249 LIST exact search, first item 2.42 2.26 250 LIST exact search, last item 6.12 6.61 251 LIST exact search, middle item 4.06 3.14 252 LIST exact search, non-item 14.07 13.47 253 LIST exact search, typed item 6.00 5.15 254 LIST exact search, untyped item 6.11 6.03 255 LIST index first element 1.72 3.99 256 LIST index last element 1.72 3.98 257 LIST index middle element 1.73 4.24 258 LIST insert an item at "end" 12.32 28.35 259 LIST insert an item at middle 13.16 29.27 260 LIST insert an item at start 12.02 28.87 261 LIST iterate list 306.19 303.42 262 LIST join list 176.87 282.94 263 LIST large, early range 4.21 9.88 264 LIST large, late range 4.16 9.91 265 LIST length, pure list 1.73 1.77 266 LIST list 6.11 5.22 267 LIST lset foreach l 498.89 497.47 268 LIST lset foreach list 497.02 496.13 269 LIST lset foreach ""s l 107.91 105.62 270 LIST lset foreach ""s list 107.92 106.40 271 LIST regexp search, first item 2.71 2.58 272 LIST regexp search, last item 33.75 81.72 273 LIST regexp search, non-item 72.41 145.18 274 LIST remove first element 11.72 28.26 275 LIST remove in mixed list 12.20 26.84 276 LIST remove last element 11.78 28.29 277 LIST remove middle element 11.76 26.74 278 LIST replace first el with multiple 12.57 28.93 279 LIST replace first element 12.43 28.35 280 LIST replace in mixed list 11.66 28.35 281 LIST replace last el with multiple 12.06 29.13 282 LIST replace last element 11.73 27.87 283 LIST replace middle el with multiple 12.03 27.43 284 LIST replace middle element 11.77 26.54 285 LIST replace range 4.78 10.79 286 LIST reverse core 11.70 12.26 287 LIST reverse lappend 338.23 330.88 288 LIST small, early range 3.01 7.84 289 LIST small, late range 3.04 6.37 290 LIST sort 299.58 700.27 291 LIST sorted search, first item 2.65 2.50 292 LIST sorted search, last item 2.69 2.63 293 LIST sorted search, middle item 2.65 2.55 294 LIST sorted search, non-item 2.75 2.54 295 LIST sorted search, typed item 2.64 3.12 296 LIST typed sort 185.31 438.83 297 LOOP for (to 1000) 205.30 202.88 298 LOOP for, iterate list 258.99 250.37 299 LOOP for, iterate string 496.13 490.03 300 LOOP foreach, iterate list 253.49 248.67 301 LOOP foreach, iterate string 342.09 338.14 302 LOOP while (to 1000) 205.26 202.68 303 LOOP while 1 (to 1000) 184.97 186.55 304 MAP ([chars])-case regsub 40.63 40.83 305 MAP http mapReply 10477.86 10474.80 306 MAP regsub -nocase, no match 471.66 472.62 307 MAP regsub 1 val 199.54 452.38 308 MAP regsub 1 val -nocase 374.97 366.54 309 MAP regsub 2 val 500.50 1163.95 310 MAP regsub 2 val -nocase 833.73 818.23 311 MAP regsub 3 val 712.43 1657.29 312 MAP regsub 3 val -nocase 1194.93 1170.34 313 MAP regsub 4 val 914.42 1531.54 314 MAP regsub 4 val -nocase 1531.77 1506.90 315 MAP regsub short 7.75 7.67 316 MAP regsub, no match 101.12 100.52 317 MAP string -nocase, no match 623.84 597.78 318 MAP string 1 val 210.92 201.27 319 MAP string 1 val -nocase 365.20 350.53 320 MAP string 2 val 373.40 366.46 321 MAP string 2 val -nocase 693.14 677.26 322 MAP string 3 val 452.10 445.25 323 MAP string 3 val -nocase 886.99 883.12 324 MAP string 4 val 555.29 544.49 325 MAP string 4 val -nocase 1118.15 2403.17 326 MAP string short 7.09 6.69 327 MAP string, no match 207.74 202.30 328 MAP |-case regsub 21.51 21.40 329 MAP |-case strmap 8.18 5.90 330 MATRIX mult 5x5 129.41 119.76 331 MATRIX mult 10x10 851.28 799.61 332 MATRIX mult 15x15 2762.41 2589.54 333 MATRIX transposition-0 1491.03 1486.67 334 MATRIX transposition-1 491.90 477.53 335 MD5 msg len 10 360.14 336.52 336 MD5 msg len 100 629.75 581.83 337 MD5 msg len 1000 4593.90 4159.05 338 MD5 msg len 10000 43482.50 52965.80 339 MTHD array stored proc call 1.93 4.80 340 MTHD call absolute 3.87 9.29 341 MTHD call relative 4.62 9.87 342 MTHD direct ns proc call 1.31 3.02 343 MTHD imported ns proc call 1.47 4.43 344 MTHD indirect proc eval 4.65 8.95 345 MTHD indirect proc eval #2 3.94 8.29 346 MTHD inline call 0.69 1.58 347 MTHD interp alias proc call 2.03 3.41 348 MTHD ns lookup call 12.54 27.36 349 MTHD switch method call 5.45 9.77 350 NS alternating 373.96 800.25 351 PARSE html form upload (7978) 2101.20 4590.55 352 PARSE html form upload (993570) 258309.4 239018.9 353 PROC do-nothing, no args 1.16 1.03 354 PROC do-nothing, one arg 1.23 1.14 355 PROC empty, no args 0.47 0.30 356 PROC empty, use args 0.30 0.30 357 PROC explicit return 1.23 1.09 358 PROC explicit return (2) 1.95 1.08 359 PROC explicit return (3) 1.26 1.93 360 PROC heavily commented 1.23 1.11 361 PROC implicit return 1.34 1.17 362 PROC implicit return (2) 1.27 1.10 363 PROC implicit return (3) 1.23 1.11 364 PROC local links with global 54.98 54.39 365 PROC local links with upvar 53.95 55.58 366 PROC local links with variable 50.87 53.25 367 RE 1-char long-end 14.32 14.85 368 RE 1-char long-end catching 22.43 21.77 369 RE 1-char long-middle 9.12 8.84 370 RE 1-char long-middle catching 16.47 15.74 371 RE 1-char long-start 3.64 3.58 372 RE 1-char long-start catching 11.48 10.54 373 RE 1-char short 4.53 3.76 374 RE 1-char short catching 10.87 10.51 375 RE basic 3.27 3.13 376 RE basic catching 12.60 11.41 377 RE c-comment long 17.58 17.36 378 RE c-comment long catching 47.35 46.96 379 RE c-comment long nomatch 26.20 26.71 380 RE c-comment long nomatch catching 27.02 27.42 381 RE c-comment long pmatch 29.50 29.38 382 RE c-comment long pmatch catching 30.21 30.20 383 RE c-comment many *s 29.92 29.87 384 RE c-comment many *s catching 79.26 78.84 385 RE c-comment nomatch 6.59 5.41 386 RE c-comment nomatch catching 6.31 5.90 387 RE c-comment simple 8.73 8.54 388 RE c-comment simple catching 31.67 30.97 389 RE count all matches 48.89 23.66 390 RE extract all matches 28.05 28.04 391 RE ini file 17384.67 17358.97 392 RE ini file ng 127.67 128.28 393 RE literal regexp 6.26 5.29 394 RE n-char long-end 14.39 14.22 395 RE n-char long-end catching 23.80 24.03 396 RE n-char long-middle 9.75 9.02 397 RE n-char long-middle catching 19.04 18.07 398 RE n-char long-start 3.82 3.67 399 RE n-char long-start catching 13.16 13.37 400 RE n-char short 3.84 3.74 401 RE n-char short catching 12.82 12.53 402 RE static anchored match 1.28 1.17 403 RE static anchored match dot 1.38 1.26 404 RE static anchored nomatch 1.29 1.17 405 RE static anchored nomatch dot 1.31 1.20 406 RE static l-anchored match 1.35 1.23 407 RE static l-anchored nomatch 1.31 1.19 408 RE static long match 5.28 5.37 409 RE static long nomatch 7.83 8.54 410 RE static r-anchored match 2.06 1.37 411 RE static r-anchored nomatch 1.47 1.37 412 RE static short match 1.46 1.30 413 RE static short nomatch 1.43 1.32 414 RE var ***= directive match 2.16 2.36 415 RE var ***= directive nomatch 2.88 2.43 416 RE var . match 2.20 2.45 417 RE var [0-9] match 5.41 5.42 418 RE var \d match 5.55 5.55 419 RE var ^$ nomatch 2.11 2.32 420 RE var backtrack case 120.56 120.15 421 RE var-based regexp 5.76 5.80 422 READ 595K, cat 50780.11 46721.31 423 READ 595K, gets 31112.43 29271.31 424 READ 595K, glob-grep match 42197.40 74673.57 425 READ 595K, glob-grep nomatch 43567.40 41210.31 426 READ 595K, read 7804.31 7820.43 427 READ 595K, read & size 7993.97 7840.51 428 READ 595K, read dyn buf 8212.11 20103.63 429 READ 595K, read small buf 62246.37 86802.66 430 READ 3050b, cat 301.57 267.54 431 READ 3050b, gets 168.79 159.90 432 READ 3050b, glob-grep match 231.87 222.84 433 READ 3050b, glob-grep nomatch 235.47 211.03 434 READ 3050b, read 48.73 47.83 435 READ 3050b, read & size 63.59 51.77 436 READ 3050b, read dyn buf 59.97 56.66 437 READ 3050b, read small buf 329.61 338.29 438 READ bin 595K, cat 27672.11 24443.34 439 READ bin 595K, gets 20112.37 17575.74 440 READ bin 595K, glob-grep match 22965.20 20741.86 441 READ bin 595K, glob-grep nomatch 22320.77 20754.71 442 READ bin 595K, read 3508.91 3503.69 443 READ bin 595K, read & size 3543.51 3514.60 444 READ bin 595K, read dyn buf 3566.37 3558.26 445 READ bin 595K, read small buf 52729.57 103596.8 446 READ bin 3050b, cat 227.80 180.64 447 READ bin 3050b, gets 123.81 109.06 448 READ bin 3050b, glob-grep match 213.87 187.56 449 READ bin 3050b, glob-grep nomatch 229.87 204.74 450 READ bin 3050b, read 29.76 29.46 451 READ bin 3050b, read & size 34.46 34.04 452 READ bin 3050b, read dyn buf 37.86 37.76 453 READ bin 3050b, read small buf 300.07 310.61 454 SHA (A) msg len 10 481.38 465.91 455 SHA (A) msg len 100 859.92 830.42 456 SHA (A) msg len 1000 6266.05 6088.15 457 SHA (A) msg len 10000 61078.90 59510.30 458 SPLIT iter, 4000 uchars 1434.44 1416.43 459 SPLIT iter, 4010 chars 1420.74 1403.90 460 SPLIT iter, rand 100 c 70.58 69.53 461 SPLIT iter, rand 1000 c 470.71 472.49 462 SPLIT iter, rand 10000 c 3701.21 7958.83 463 SPLIT on 'c', 4000 uchars 66.83 66.78 464 SPLIT on 'c', 4010 chars 64.33 62.94 465 SPLIT on 'cz', 4000 uchars 178.61 177.00 466 SPLIT on 'cz', 4010 chars 161.14 163.64 467 SPLIT on 'cû', 4000 uchars 228.22 228.84 468 SPLIT on 'cû', 4010 chars 168.35 169.86 469 SPLIT, 4000 uchars 428.96 427.73 470 SPLIT, 4010 chars 409.63 410.00 471 SPLIT, rand 100 c 46.12 45.98 472 SPLIT, rand 1000 c 217.34 217.88 473 SPLIT, rand 10000 c 1179.41 1226.39 474 STR append 23.94 9.93 475 STR append (1KB + 1KB) 12.26 4.80 476 STR append (1MB + (1b+1K+1b)*100) 4797.20 4784.05 477 STR append (1MB + 1KB) 4367.65 4343.07 478 STR append (1MB + 1KB*20) 4440.72 4424.53 479 STR append (1MB + 1KB*1000) 7988.49 8182.70 480 STR append (1MB + 1MB*3) 16621.94 16625.88 481 STR append (1MB + 1MB*5) 21377.44 20956.88 482 STR append (1MB + 2b*1000) 6126.61 4673.56 483 STR append (10KB + 1KB) 21.91 9.65 484 STR first (failure) 14.00 13.70 485 STR first (failure) utf 13.27 13.09 486 STR first (success) 3.00 2.77 487 STR first (success) utf 2.98 2.83 488 STR first (total failure) 11.10 11.18 489 STR first (total failure) utf 11.76 11.59 490 STR index 0 2.77 2.46 491 STR index 100 2.81 2.48 492 STR index 500 2.75 2.73 493 STR info locals match 90.03 88.84 494 STR last (failure) 10.94 10.71 495 STR last (success) 2.86 2.64 496 STR last (total failure) 9.38 9.07 497 STR length (==4010) 1.71 1.72 498 STR length growing (1000) 326.12 331.07 499 STR length growing uc (1000) 321.70 325.03 500 STR length of a LIST 1.70 1.68 501 STR length static str 1.33 1.15 502 STR match, complex (failure) 27.34 27.32 503 STR match, complex (success early) 2.18 2.88 504 STR match, complex (success late) 33.10 32.47 505 STR match, complex (total failure) 22.50 22.98 506 STR match, exact (failure) 1.28 1.18 507 STR match, exact (success) 1.28 1.15 508 STR match, exact -nocase (failure) 1.36 1.22 509 STR match, exact -nocase (success) 1.94 1.80 510 STR match, recurse (fail backtrack) 176.04 175.01 511 STR match, recurse (fail bt1) 183.55 183.13 512 STR match, recurse (fail bt2) 177.18 176.01 513 STR match, recurse (fail ranchor) 37186.41 37180.38 514 STR match, recurse (success bt2) 18.10 17.52 515 STR match, recurse2 (fail) 48438.01 43934.44 516 STR match, recurse2 (success) 27.07 26.91 517 STR match, simple (failure) 1.37 1.23 518 STR match, simple (success) 1.41 1.25 519 STR range, index 100..200 of 4010 3.85 3.28 520 STR repeat, 4010 chars * 10 16.31 15.62 521 STR repeat, 4010 chars * 100 1423.39 1427.72 522 STR repeat, abcdefghij * 10 2.98 3.10 523 STR repeat, abcdefghij * 100 5.14 4.53 524 STR repeat, abcdefghij * 1000 27.07 25.86 525 STR replace, equal replacement 7.53 6.34 526 STR replace, longer replacement 7.13 6.24 527 STR replace, no replacement 6.57 5.75 528 STR reverse core, 10 c 3.91 3.31 529 STR reverse core, 10 uc 4.10 3.69 530 STR reverse core, 100 c 4.58 3.93 531 STR reverse core, 100 uc 4.82 4.36 532 STR reverse core, 400 c 16.04 6.18 533 STR reverse core, 400 uc 15.13 5.94 534 STR reverse iter/append, 10 c 10.22 10.19 535 STR reverse iter/append, 10 uc 10.93 9.96 536 STR reverse iter/append, 100 c 64.69 62.74 537 STR reverse iter/append, 100 uc 68.24 66.68 538 STR reverse iter/append, 400 c 244.48 234.91 539 STR reverse iter/append, 400 uc 262.31 256.29 540 STR reverse iter/set, 10 c 10.43 9.60 541 STR reverse iter/set, 10 uc 11.76 10.05 542 STR reverse iter/set, 100 c 80.56 78.46 543 STR reverse iter/set, 100 uc 87.84 85.31 544 STR reverse iter/set, 400 c 348.89 337.55 545 STR reverse iter/set, 400 uc 369.86 356.89 546 STR reverse recursive, 10 c 39.17 31.87 547 STR reverse recursive, 10 uc 38.42 30.94 548 STR reverse recursive, 100 c 371.94 327.19 549 STR reverse recursive, 100 uc 368.33 324.96 550 STR reverse recursive, 400 c 1557.84 3019.51 551 STR reverse recursive, 400 uc 3168.02 3198.39 552 STR str $a eq $b 2.66 2.61 553 STR str $a eq $b (same obj) 2.78 2.77 554 STR str $a equal "" 1.84 1.79 555 STR str $a ne $b 2.80 2.66 556 STR str $a ne $b (same obj) 2.64 2.61 557 STR str num == "" 2.10 1.90 558 STR string compare 2.60 3.33 559 STR string compare "" 2.39 2.29 560 STR string compare long 22.77 22.12 561 STR string compare long (same obj) 2.37 2.35 562 STR string compare mixed long 35.19 34.60 563 STR string compare uni long 35.76 35.67 564 STR string equal "" 2.07 1.94 565 STR string equal long (!= len) 4.50 3.97 566 STR string equal long (== len) 50.38 50.18 567 STR string equal long (same obj) 2.82 2.78 568 STR string equal mixed long 2.76 2.68 569 STR string equal uni long 57.75 57.82 570 STR/LIST length, obj shimmer 342.93 344.01 571 SWITCH 1st true 1.82 1.66 572 SWITCH 2nd true 1.76 1.66 573 SWITCH 9th true 1.79 2.31 574 SWITCH default true 1.77 1.62 575 TRACE all set (rwu) 4.24 3.63 576 TRACE no trace set 4.29 3.68 577 TRACE read 4.19 3.62 578 TRACE unset 4.17 3.76 579 TRACE write 4.96 3.62 580 UNSET catch var !exist 12.90 13.59 581 UNSET catch var exists 1.85 1.58 582 UNSET info check var !exist 2.19 1.27 583 UNSET info check var exists 1.86 1.59 584 UNSET nocomplain var !exist 1.82 1.54 585 UNSET nocomplain var exists 1.78 1.53 586 UNSET var exists 1.87 1.47 587 VAR 'array set' of 100 elems 22.81 23.05 588 VAR 100 'set's in array 19.47 20.13 589 VAR access global 2.28 2.22 590 VAR access local proc arg 1.63 1.55 591 VAR access locally set 1.61 1.45 592 VAR access upvar 2.35 2.24 593 VAR incr global var 1000x 408.53 394.77 594 VAR incr local var 1000x 410.48 407.78 595 VAR incr upvar var 1000x 389.75 385.85 596 VAR mset 2.77 2.14 597 VAR mset (foreach) 2.69 1.92 598 VAR ref absolute 110.97 115.35 599 VAR ref local 8.79 9.04 600 VAR ref variable 10.21 10.09 601 VAR set array element 2.07 2.04 602 VAR set scalar 1.33 1.17 603 WORDCOUNT wc1 645.88 641.12 604 WORDCOUNT wc2 165.22 161.90 605 WORDCOUNT wc3 151.97 147.80 605 BENCHMARKS 1:8.5.2b1 2:8.5.2b1 FINISHED 2008-03-04 23:28:03 ---- Here is a list excluding differences smaller than 10% and marking +/- [RT] 7March08 007 BASE64 decode 10000 58787.80 103005.3 - 008 BASE64 decode2 10 84.76 74.16 + 011 BASE64 decode2 10000 57363.40 132742.6 - 015 BASE64 decode3 10000 29059.10 65912.10 - 020 BASE64 encode2 10 46.53 40.00 + 021 BASE64 encode2 100 356.77 312.75 + 022 BASE64 encode2 1000 3343.10 3004.10 + 023 BASE64 encode2 10000 33407.50 29449.40 + 029 BIN bitset-v1 5000 chars 18223.34 30303.85 - 030 BIN bitset-v1 10000 chars 35986.62 63433.68 - 031 BIN bitset-v2 1000 chars 2281.68 2049.22 + 032 BIN bitset-v2 5000 chars 11147.60 9889.81 + 042 CATCH error, complex 15.80 13.84 + 043 CATCH no catch used 4.89 4.33 + 044 CATCH return error 16.31 13.85 + 045 CATCH return except 5.24 4.12 + 056 ENC iso8859-2, read & size 127.30 103.03 + 058 EVAL cmd eval as list 3.21 2.81 + 060 EVAL cmd eval in list obj var 3.29 2.94 + 066 EXPR $a == $b int 1.73 2.27 - 068 EXPR $a == $b str (== len) 4.64 3.74 + 069 EXPR braced 5.50 4.56 + 072 EXPR incr with incr 1.27 1.13 + 073 EXPR inline 6.10 5.41 + 074 EXPR one operand 1.34 1.16 + 083 FILE exists tmpfile (obj) 4.16 3.74 + 086 FILE exists! tmpfile (str) 7.27 8.96 - 088 FILE glob / all subcommands 9391.12 11242.17 - 090 FILE glob / attributes 5794.90 13841.92 - 096 FILE glob / isfile 801.31 1856.42 - 097 FILE glob / mtime 802.94 1827.71 - 098 FILE glob / owned 816.73 1884.02 - 099 FILE glob / readable 800.29 1849.52 - 100 FILE glob / rootname 205.63 468.79 - 101 FILE glob / size 805.67 1873.71 - 102 FILE glob / tail 155.65 380.19 - 103 FILE glob / writable 808.97 1830.76 - 108 GCCont_cpb::cGCC 5000 3903.84 9373.96 - 120 GCCont_cpbrs::cGCC1 5000 1115.96 2646.38 - 123 GCCont_cpbrs::cGCC2 5000 1028.94 2361.30 - 126 GCCont_cpbrs_trap::cGCC 5000 5535.34 13290.76 - 132 GCCont_i::cGCC1 5000 4133.44 9659.00 - 135 GCCont_i::cGCC2 5000 3701.06 8622.28 - 138 GCCont_i::cGCC3 5000 2841.40 6529.74 - 147 GCCont_r3::cGCC 5000 4563.44 8070.34 - 150 GCCont_rsf1::cGCC 5000 3417.50 7976.76 - 153 GCCont_rsf2::cGCC1 5000 1770.86 4102.58 - 156 GCCont_rsf2::cGCC2 5000 1714.64 3984.60 - 159 GCCont_rsf3::cGCC 5000 1714.16 3856.40 - 171 IF else true numeric 2.24 1.96 + 185 KLIST shuffle0 llength 1 12.03 9.56 + 190 KLIST shuffle1-s llength 1 6.86 9.60 - 191 KLIST shuffle1-s llength 10 49.71 43.46 + 193 KLIST shuffle1-s llength 1000 21294.60 39023.67 - 194 KLIST shuffle1a llength 1 9.43 26.69 - 195 KLIST shuffle1a llength 10 64.12 137.48 - 196 KLIST shuffle1a llength 100 625.15 1307.92 - 197 KLIST shuffle1a llength 1000 6260.57 11679.23 - 204 KLIST shuffle3 llength 1 7.41 9.65 - 205 KLIST shuffle3 llength 10 48.93 43.40 + 206 KLIST shuffle3 llength 100 463.71 412.72 + 209 KLIST shuffle4 llength 1 7.45 8.91 - 214 KLIST shuffle5-s llength 1 5.96 5.02 + 215 KLIST shuffle5-s llength 10 40.55 32.59 + 216 KLIST shuffle5-s llength 100 450.02 371.67 + 217 KLIST shuffle5-s llength 1000 8233.00 9302.82 - 218 KLIST shuffle5a llength 1 7.21 5.78 + 219 KLIST shuffle5a llength 10 48.97 40.01 + 220 KLIST shuffle5a llength 100 464.08 374.32 + 221 KLIST shuffle5a llength 1000 4730.71 3867.87 + 222 KLIST shuffle5a llength 10000 66777.50 139490.1 - 223 KLIST shuffle6 llength 1 2.10 4.20 - 224 KLIST shuffle6 llength 10 22.09 46.78 - 225 KLIST shuffle6 llength 100 210.15 427.52 - 226 KLIST shuffle6 llength 1000 2125.62 4319.75 - 227 KLIST shuffle6 llength 10000 22624.80 50686.40 - 228 LIST append to list 2.77 4.85 - 233 LIST concat CONCAT 2x10 7.50 3.73 + 241 LIST concat FOREACH/LAPPEND 2x10 7.45 16.66 - 242 LIST concat FOREACH/LAPPEND 2x100 42.04 97.86 - 243 LIST concat FOREACH/LAPPEND 2x1000 345.47 839.29 - 244 LIST concat FOREACH/LAPPEND 2x10000 3698.54 7157.24 - 251 LIST exact search, middle item 4.06 3.14 + 253 LIST exact search, typed item 6.00 5.15 + 255 LIST index first element 1.72 3.99 - 256 LIST index last element 1.72 3.98 - 257 LIST index middle element 1.73 4.24 - 258 LIST insert an item at "end" 12.32 28.35 - 259 LIST insert an item at middle 13.16 29.27 - 260 LIST insert an item at start 12.02 28.87 - 262 LIST join list 176.87 282.94 - 263 LIST large, early range 4.21 9.88 - 264 LIST large, late range 4.16 9.91 - 266 LIST list 6.11 5.22 + 272 LIST regexp search, last item 33.75 81.72 - 273 LIST regexp search, non-item 72.41 145.18 - 274 LIST remove first element 11.72 28.26 - 275 LIST remove in mixed list 12.20 26.84 - 276 LIST remove last element 11.78 28.29 - 277 LIST remove middle element 11.76 26.74 - 278 LIST replace first el with multiple 12.57 28.93 - 279 LIST replace first element 12.43 28.35 - 280 LIST replace in mixed list 11.66 28.35 - 281 LIST replace last el with multiple 12.06 29.13 - 282 LIST replace last element 11.73 27.87 - 283 LIST replace middle el with multiple 12.03 27.43 - 284 LIST replace middle element 11.77 26.54 - 285 LIST replace range 4.78 10.79 - 288 LIST small, early range 3.01 7.84 - 289 LIST small, late range 3.04 6.37 - 290 LIST sort 299.58 700.27 - 295 LIST sorted search, typed item 2.64 3.12 - 296 LIST typed sort 185.31 438.83 - 307 MAP regsub 1 val 199.54 452.38 - 309 MAP regsub 2 val 500.50 1163.95 - 311 MAP regsub 3 val 712.43 1657.29 - 313 MAP regsub 4 val 914.42 1531.54 - 325 MAP string 4 val -nocase 1118.15 2403.17 - 329 MAP |-case strmap 8.18 5.90 + 338 MD5 msg len 10000 43482.50 52965.80 - 339 MTHD array stored proc call 1.93 4.80 - 340 MTHD call absolute 3.87 9.29 - 341 MTHD call relative 4.62 9.87 - 342 MTHD direct ns proc call 1.31 3.02 - 343 MTHD imported ns proc call 1.47 4.43 - 344 MTHD indirect proc eval 4.65 8.95 - 345 MTHD indirect proc eval #2 3.94 8.29 - 346 MTHD inline call 0.69 1.58 - 347 MTHD interp alias proc call 2.03 3.41 - 348 MTHD ns lookup call 12.54 27.36 - 349 MTHD switch method call 5.45 9.77 - 350 NS alternating 373.96 800.25 - 351 PARSE html form upload (7978) 2101.20 4590.55 - 353 PROC do-nothing, no args 1.16 1.03 + 355 PROC empty, no args 0.47 0.30 + 357 PROC explicit return 1.23 1.09 + 358 PROC explicit return (2) 1.95 1.08 + 359 PROC explicit return (3) 1.26 1.93 - 361 PROC implicit return 1.34 1.17 + 362 PROC implicit return (2) 1.27 1.10 + 373 RE 1-char short 4.53 3.76 + 385 RE c-comment nomatch 6.59 5.41 + 389 RE count all matches 48.89 23.66 + 393 RE literal regexp 6.26 5.29 + 410 RE static r-anchored match 2.06 1.37 + 412 RE static short match 1.46 1.30 + 415 RE var ***= directive nomatch 2.88 2.43 + 416 RE var . match 2.20 2.45 - 424 READ 595K, glob-grep match 42197.40 74673.57 - 428 READ 595K, read dyn buf 8212.11 20103.63 - 429 READ 595K, read small buf 62246.37 86802.66 - 430 READ 3050b, cat 301.57 267.54 + 433 READ 3050b, glob-grep nomatch 235.47 211.03 + 435 READ 3050b, read & size 63.59 51.77 + 438 READ bin 595K, cat 27672.11 24443.34 + 439 READ bin 595K, gets 20112.37 17575.74 + 445 READ bin 595K, read small buf 52729.57 103596.8 - 446 READ bin 3050b, cat 227.80 180.64 + 447 READ bin 3050b, gets 123.81 109.06 + 448 READ bin 3050b, glob-grep match 213.87 187.56 + 449 READ bin 3050b, glob-grep nomatch 229.87 204.74 + 462 SPLIT iter, rand 10000 c 3701.21 7958.83 - 474 STR append 23.94 9.93 + 475 STR append (1KB + 1KB) 12.26 4.80 + 482 STR append (1MB + 2b*1000) 6126.61 4673.56 + 483 STR append (10KB + 1KB) 21.91 9.65 + 490 STR index 0 2.77 2.46 + 491 STR index 100 2.81 2.48 + 501 STR length static str 1.33 1.15 + 503 STR match, complex (success early) 2.18 2.88 - 507 STR match, exact (success) 1.28 1.15 + 508 STR match, exact -nocase (failure) 1.36 1.22 + 517 STR match, simple (failure) 1.37 1.23 + 518 STR match, simple (success) 1.41 1.25 + 519 STR range, index 100..200 of 4010 3.85 3.28 + 523 STR repeat, abcdefghij * 100 5.14 4.53 + 525 STR replace, equal replacement 7.53 6.34 + 526 STR replace, longer replacement 7.13 6.24 + 527 STR replace, no replacement 6.57 5.75 + 528 STR reverse core, 10 c 3.91 3.31 + 530 STR reverse core, 100 c 4.58 3.93 + 532 STR reverse core, 400 c 16.04 6.18 + 533 STR reverse core, 400 uc 15.13 5.94 + 541 STR reverse iter/set, 10 uc 11.76 10.05 + 546 STR reverse recursive, 10 c 39.17 31.87 + 547 STR reverse recursive, 10 uc 38.42 30.94 + 548 STR reverse recursive, 100 c 371.94 327.19 + 549 STR reverse recursive, 100 uc 368.33 324.96 + 550 STR reverse recursive, 400 c 1557.84 3019.51 - 558 STR string compare 2.60 3.33 - 565 STR string equal long (!= len) 4.50 3.97 + 573 SWITCH 9th true 1.79 2.31 - 575 TRACE all set (rwu) 4.24 3.63 + 576 TRACE no trace set 4.29 3.68 + 577 TRACE read 4.19 3.62 + 579 TRACE write 4.96 3.62 + 581 UNSET catch var exists 1.85 1.58 + 582 UNSET info check var !exist 2.19 1.27 + 583 UNSET info check var exists 1.86 1.59 + 584 UNSET nocomplain var !exist 1.82 1.54 + 585 UNSET nocomplain var exists 1.78 1.53 + 586 UNSET var exists 1.87 1.47 + 596 VAR mset 2.77 2.14 + 597 VAR mset (foreach) 2.69 1.92 + 602 VAR set scalar 1.33 1.17 + <> Performance | Tcl Implementations