Version 27 of Tcl Benchmarks

Updated 2010-09-28 03:51:55 by JH

Jeffrey Hobbs: There have been discussions about the changing relative speed of Tcl over the years (primarily rotating around the addition of the byte-code compiler - faster, but then also the changes to support i18n - slower).

I created the tclbench [L1 ] application to get a better understanding of what has truly happened to performance over the years, with the forward looking view of finding the pain points and fixing them. Anyone can get tclbench from CVS [L2 ] to do relative benchmarks themselves, but below I've posted the results from a full run over the benchmark suite. All builds represent the final code of that version.

A few have noted that these numbers aren't the easiest to read overall, which I can agree with. Take a look at the Tcl Normalized Benchmarks that set 8.4 as a norm of 1.0 to compare against. For those looking for more complete version-by-version comparisons, see Tcl Extended Benchmarks.

If you've got BLT handy, then here is a little code for Plotting Tcl Benchmarks.

The speed enhancements in 8.4 are primarily achieved by work done by myself (JH) and Eric Melski at Ajuba and continued at ActiveState. Addition optimizations are also done by Miguel Sofer. Additional major enhancements in 8.5 done by JH, Miguel Sofer and Donal Fellows. 8.5 added bignums, which slowed down expr handling in general. 8.6 has a new non-recursive (stackless) bytecode engine.

For those interested in the use of threads for concurrent processing, please see the Tcl Benchmarks with Threads.

The numbers are microseconds, but you should only look at them relative to each other. Lower is better. There is some fluctuation expected as Tcl's 'time' does wall timing, not true cpu time. In any case, these were done on a 2.66ghz Intel i7 MBP with 8GB physmem running OS X 10.6.4. All interpreters were compiled static with no threads using gcc 4.2.1 (Apple Inc. build 5664) with -O2 (no -mcpu modifiers). The "elapsed" time can also be misleading because runbench v1.23+ uses an autoscaling check to try and make sure each test runs at least .1s and at most 4s. Also, as interp version gets older, fewer tests are run.


 TCL_INTERP: 1:8.6b1.2 2:8.5.9 3:8.4.19 4:8.3.5 5:8.2.3 6:8.0.5 7:7.6p2
 STARTED 2010-09-27 19:45:28 (runbench.tcl v1.23)
 Benchmark 1:8.6b1.2 /Users/jeffh/install/Darwin/bin/canon8.6
 aabbccdeeeffghkllmmmmnpprrssstuuvw 00:02:10 elapsed
 126703 milliseconds
 Benchmark 2:8.5.9 /Users/jeffh/install/Darwin/bin/canon8.5
 aabbccdeeeffghkllmmmmnpprrssstuuvw 00:01:56 elapsed
 112382 milliseconds
 Benchmark 3:8.4.19 /Users/jeffh/install/Darwin/bin/canon8.4
 aabbccdeeeffghkllmmmmnpprrssstuuvw 00:01:33 elapsed
 89092 milliseconds
 Benchmark 4:8.3.5 /Users/jeffh/install/Darwin/bin/canon8.3
 aabbccdeeeffghkllmmmmnpprrssstuuvw 00:01:59 elapsed
 116928 milliseconds
 Benchmark 5:8.2.3 /Users/jeffh/install/Darwin/bin/canon8.2
 aabbccdeeeffghkllmmmmnpprrssstuuvw 00:02:02 elapsed
 123218 milliseconds
 Benchmark 6:8.0.5 /Users/jeffh/install/Darwin/bin/canon8.0
 aabbccdeeeffghkllmmmmnpprrssstuuvw 00:01:43 elapsed
 104254 milliseconds
 Benchmark 7:7.6p2 /Users/jeffh/install/Darwin/bin/canon7.6
 aabbccdeeeffghkllmmmmnpprrssstuuvw 00:02:33 elapsed
 154203 milliseconds
000VERSIONS:1:8.6b1.22:8.5.93:8.4.194:8.3.55:8.2.36:8.0.57:7.6p2
001ARRAY genKeys 501.000.930.420.510.520.440.73
002ARRAY genKeys 5001.000.960.420.530.540.470.75
003ARRAY makeHash 500 501.000.930.880.891.051.081.31
004ascii85 strlen 26901.000.740.56-=--=--=--=-
005ascii85 strlen 2690001.000.790.60-=--=--=--=-
006BASE64 decode 101.000.930.961.131.131.22-=-
007BASE64 decode 1001.000.890.951.181.281.39-=-
008BASE64 decode 10001.000.860.961.211.371.44-=-
009BASE64 decode 100001.000.880.961.211.351.46-=-
010BASE64 decode2 101.000.920.961.131.101.19-=-
011BASE64 decode2 1001.000.931.011.221.311.43-=-
012BASE64 decode2 10001.000.921.031.281.421.52-=-
013BASE64 decode2 100001.000.921.041.311.421.54-=-
014BASE64 decode3 101.000.820.720.960.960.96-=-
015BASE64 decode3 1001.000.850.791.271.261.21-=-
016BASE64 decode3 10001.000.830.791.371.351.28-=-
017BASE64 decode3 100001.000.810.781.381.341.30-=-
018BASE64 encode 101.000.860.721.081.081.27-=-
019BASE64 encode 1001.000.890.721.171.271.65-=-
020BASE64 encode 10001.000.880.711.231.331.70-=-
021BASE64 encode 100001.000.870.691.191.291.68-=-
022BASE64 encode2 101.000.900.961.511.401.72-=-
023BASE64 encode2 1001.000.900.971.771.802.31-=-
024BASE64 encode2 10001.000.880.971.811.872.43-=-
025BASE64 encode2 100001.000.910.981.801.862.45-=-
026BASE64 encode3 101.000.900.770.980.920.92-=-
027BASE64 encode3 1001.000.890.961.751.731.65-=-
028BASE64 encode3 10001.000.871.062.152.142.01-=-
029BASE64 encode3 100001.000.871.062.192.212.03-=-
030BIN bitset-v1 1000 chars1.000.710.330.310.350.34-=-
031BIN bitset-v1 5000 chars1.000.730.310.300.360.35-=-
032BIN bitset-v1 10000 chars1.000.720.330.290.360.35-=-
033BIN bitset-v2 1000 chars1.000.670.320.390.390.37-=-
034BIN bitset-v2 5000 chars1.000.670.300.400.380.39-=-
035BIN bitset-v2 10000 chars1.000.670.290.390.370.39-=-
036BIN bitset-v3 1000 chars1.000.810.641.091.141.07-=-
037BIN bitset-v3 5000 chars1.000.810.631.351.421.34-=-
038BIN bitset-v3 10000 chars1.000.810.631.401.481.39-=-
039BIN c scan, 1000b1.000.970.950.240.240.36-=-
040BIN c scan, 5000b1.000.980.920.480.470.48-=-
041BIN c scan, 10000b1.000.970.920.530.530.53-=-
042BIN chars, 10000b1.000.810.621.421.511.45-=-
043BIN random string 100b1.000.740.280.380.400.39-=-
044BIN random string 5000b1.000.720.280.370.380.38-=-
045BIN u char, 10000b1.000.98-=--=--=--=--=-
046CATCH error, complex1.000.850.310.250.250.250.37
047CATCH no catch used1.000.910.200.000.000.000.72
048CATCH return error1.000.830.310.240.240.240.36
049CATCH return except1.000.900.200.340.000.340.67
050CATCH return ok1.000.930.200.330.330.330.66
051DATA access in a list1.001.111.183.052.942.8856.23
052DATA access in an array1.000.880.540.900.900.882.84
053DATA create in a list1.001.150.973.283.573.349.38
054DATA create in an array1.000.990.901.031.031.322.17
055ENC iso2022-jp, gets1.000.991.240.440.40-=--=-
056ENC iso2022-jp, read1.000.991.190.410.40-=--=-
057ENC iso2022-jp, read & size1.001.011.200.410.41-=--=-
058ENC iso8859-2, gets1.002.363.831.921.81-=--=-
059ENC iso8859-2, read1.003.175.542.472.38-=--=-
060ENC iso8859-2, read & size1.002.824.522.222.11-=--=-
061EVAL cmd and mixed lists1.000.840.280.240.600.410.05
062EVAL cmd eval as list1.000.850.570.771.541.540.77
063EVAL cmd eval as string1.001.040.470.450.450.450.23
064EVAL cmd eval in list obj var1.000.850.560.480.971.450.97
065EVAL cmd eval in list obj {*}1.000.848.5+8.5+8.5+8.5+8.5+
066EVAL list cmd and mixed lists1.000.840.280.240.610.410.05
067EVAL list cmd and pure lists1.001.001.611.0249.0433.374.20
068EXPR $a != $b dbl1.000.790.340.000.000.822.46
069EXPR $a != $b int1.000.500.220.000.000.542.16
070EXPR $a != $b str (!= len)1.000.570.700.680.680.682.70
071EXPR $a != $b str (== len)1.000.560.740.660.660.662.63
072EXPR $a == $b dbl1.000.730.320.000.000.753.01
073EXPR $a == $b int1.000.540.220.000.000.542.17
074EXPR $a == $b str (!= len)1.000.580.710.670.670.672.68
075EXPR $a == $b str (== len)1.000.831.000.910.910.913.64
076EXPR braced1.000.790.420.480.480.483.37
077EXPR builtin dyn1.000.900.330.220.220.330.33
078EXPR builtin sin1.000.780.410.001.230.002.47
079EXPR cast double1.000.810.330.000.000.001.90
080EXPR cast int1.000.830.320.000.000.001.85
081EXPR fifty operands1.000.930.710.580.581.175.26
082EXPR incr with expr1.000.780.350.000.000.001.39
083EXPR incr with incr1.000.750.330.000.000.001.37
084EXPR inline1.000.840.700.620.620.621.24
085EXPR one operand1.000.800.360.000.000.001.43
086EXPR rand range1.000.750.250.000.000.00-=-
087EXPR rand range func1.000.860.390.560.560.561.67
088EXPR ten operands1.000.820.490.000.001.122.25
089EXPR unbraced1.000.920.410.280.280.340.34
090EXPR unbraced long1.001.001.050.830.860.500.50
091FCOPY binary: 160K1.000.960.960.950.99-=--=-
092FCOPY encoding: 160K1.001.000.990.750.80-=--=-
093FCOPY std: 160K1.000.950.960.951.000.951.83
094FILE exec interp1.000.950.860.330.270.310.21
095FILE exec interp: pkg require1.000.960.760.330.280.210.14
096FILE exists tmpfile (obj)1.000.920.830.860.860.860.86
097FILE exists ~1.000.880.731.152.300.770.77
098FILE exists! tmpfile (obj)1.000.970.450.970.970.650.65
099FILE exists! tmpfile (str)1.000.963.290.600.600.600.40
100FILE glob tmpdir (60 entries)1.001.011.110.740.740.640.63
101FILE glob / all subcommands1.000.970.590.660.670.510.50
102FILE glob / atime1.000.991.690.590.670.590.65
103FILE glob / attributes1.000.990.460.320.33-=--=-
104FILE glob / dirname1.000.982.561.101.321.271.14
105FILE glob / executable1.000.991.740.590.650.590.58
106FILE glob / exists1.000.961.740.560.620.560.56
107FILE glob / extension1.000.971.480.770.980.930.86
108FILE glob / isdirectory1.000.981.720.590.660.600.59
109FILE glob / isfile1.000.981.680.590.660.600.58
110FILE glob / mtime1.000.971.650.580.650.590.65
111FILE glob / owned1.000.971.640.600.670.600.57
112FILE glob / readable1.000.971.740.580.630.570.57
113FILE glob / rootname1.000.961.310.690.870.820.78
114FILE glob / size1.000.981.680.590.660.590.66
115FILE glob / tail1.000.962.031.011.231.141.06
116FILE glob / writable1.000.971.740.580.630.570.57
117FILE recurse / -dir1.000.961.210.770.780.870.81
118FILE recurse / cd1.000.901.410.480.470.530.49
119GCCont_cpb::cGCC 501.000.910.811.511.771.69-=-
120GCCont_cpb::cGCC 5001.000.930.681.882.412.28-=-
121GCCont_cpb::cGCC 50001.000.940.641.962.612.47-=-
122GCCont_cpbre1::cGCC 501.000.940.770.84-=--=--=-
123GCCont_cpbre1::cGCC 5001.001.030.960.98-=--=--=-
124GCCont_cpbre1::cGCC 50001.001.010.990.99-=--=--=-
125GCCont_cpbre2::cGCC 501.000.950.860.89-=--=--=-
126GCCont_cpbre2::cGCC 5001.000.991.020.98-=--=--=-
127GCCont_cpbre2::cGCC 50001.001.011.001.00-=--=--=-
128GCCont_cpbrs2::cGCC 501.000.980.712.011.93-=--=-
129GCCont_cpbrs2::cGCC 5001.001.151.055.585.48-=--=-
130GCCont_cpbrs2::cGCC 50001.001.291.237.947.98-=--=-
131GCCont_cpbrs::cGCC1 501.000.960.461.361.280.99-=-
132GCCont_cpbrs::cGCC1 5001.001.060.834.444.421.17-=-
133GCCont_cpbrs::cGCC1 50001.001.241.278.528.521.44-=-
134GCCont_cpbrs::cGCC2 501.001.010.471.571.531.05-=-
135GCCont_cpbrs::cGCC2 5001.001.130.845.165.401.22-=-
136GCCont_cpbrs::cGCC2 50001.001.311.309.989.911.40-=-
137GCCont_cpbrs_trap::cGCC 501.000.990.810.870.840.57-=-
138GCCont_cpbrs_trap::cGCC 5001.001.000.961.010.990.54-=-
139GCCont_cpbrs_trap::cGCC 50001.001.021.001.041.030.54-=-
140GCCont_expr::cGCC 501.000.990.840.730.73-=--=-
141GCCont_expr::cGCC 5001.001.041.421.301.29-=--=-
142GCCont_expr::cGCC 50001.001.0610.1610.2410.21-=--=-
143GCCont_i::cGCC1 501.000.891.501.832.031.98-=-
144GCCont_i::cGCC1 5001.000.901.732.222.582.49-=-
145GCCont_i::cGCC1 50001.000.901.882.342.702.56-=-
146GCCont_i::cGCC2 501.000.930.711.011.311.25-=-
147GCCont_i::cGCC2 5001.000.950.681.091.611.56-=-
148GCCont_i::cGCC2 50001.000.950.681.111.671.63-=-
149GCCont_i::cGCC3 501.000.900.761.081.421.35-=-
150GCCont_i::cGCC3 5001.000.910.771.251.871.79-=-
151GCCont_i::cGCC3 50001.000.910.781.271.961.88-=-
152GCCont_r1::cGCC 501.000.901.742.302.402.45-=-
153GCCont_r1::cGCC 5001.000.901.802.392.462.46-=-
154GCCont_r1::cGCC 50001.000.911.822.372.502.48-=-
155GCCont_r2::cGCC 501.000.901.631.992.092.04-=-
156GCCont_r2::cGCC 5001.000.861.812.262.612.46-=-
157GCCont_r2::cGCC 50001.000.871.882.392.732.57-=-
158GCCont_r3::cGCC 501.000.891.581.922.122.02-=-
159GCCont_r3::cGCC 5001.000.871.832.272.632.46-=-
160GCCont_r3::cGCC 50001.000.871.862.292.682.49-=-
161GCCont_rsf1::cGCC 501.000.910.750.871.26-=--=-
162GCCont_rsf1::cGCC 5001.000.980.841.061.81-=--=-
163GCCont_rsf1::cGCC 50001.001.000.871.081.95-=--=-
164GCCont_rsf2::cGCC1 501.000.910.700.871.14-=--=-
165GCCont_rsf2::cGCC1 5001.000.970.851.221.83-=--=-
166GCCont_rsf2::cGCC1 50001.001.010.891.372.05-=--=-
167GCCont_rsf2::cGCC2 501.000.890.740.891.13-=--=-
168GCCont_rsf2::cGCC2 5001.000.970.851.151.78-=--=-
169GCCont_rsf2::cGCC2 50001.001.010.901.272.00-=--=-
170GCCont_rsf3::cGCC 501.000.900.750.801.12-=--=-
171GCCont_rsf3::cGCC 5001.000.980.861.151.77-=--=-
172GCCont_rsf3::cGCC 50001.001.010.881.231.96-=--=-
173GCCont_turing::cGCC 501.001.080.881.231.11-=--=-
174GCCont_turing::cGCC 5001.001.261.191.952.06-=--=-
175GCCont_turing::cGCC 50001.001.351.342.312.25-=--=-
176HEAPSORT size 101.000.920.730.930.919.865.05
177HEAPSORT size 501.000.890.690.940.916.684.50
178HEAPSORT size 1001.000.900.690.900.875.844.35
179HEAPSORT2 size 101.000.911.13-=--=--=--=-
180HEAPSORT2 size 501.000.921.11-=--=--=--=-
181HEAPSORT2 size 1001.000.921.14-=--=--=--=-
182IF 1/0 check1.000.780.381.321.321.322.63
183IF else true al1.000.841.110.850.850.853.39
184IF else true numeric1.000.850.701.081.081.084.30
185IF elseif true al1.000.840.800.810.810.813.23
186IF elseif true numeric1.000.830.521.021.021.024.08
187IF if false al/al1.000.880.540.760.760.762.29
188IF if false al/num1.000.840.430.750.750.753.73
189IF if false num/num1.000.810.310.810.810.813.23
190IF if true al1.000.840.591.021.021.023.06
191IF if true al/al1.000.850.500.850.850.852.56
192IF if true num/num1.000.810.420.930.930.933.74
193IF if true numeric1.000.810.450.000.000.003.23
194IF multi 1st true1.000.810.490.000.000.005.56
195IF multi 2nd true1.000.810.521.041.041.045.21
196IF multi 9th true1.000.810.620.750.750.756.72
197IF multi default true1.000.840.670.790.790.797.94
198KLIST shuffle0 llength 11.000.920.881.291.291.298.0+
199KLIST shuffle0 llength 101.000.940.891.361.361.438.0+
200KLIST shuffle0 llength 1001.000.950.991.621.611.668.0+
201KLIST shuffle0 llength 10001.000.951.081.701.691.758.0+
202KLIST shuffle0 llength 100001.000.961.281.841.781.86-=-
203KLIST shuffle1-s llength 11.000.811.221.541.541.155.00
204KLIST shuffle1-s llength 101.000.820.780.810.960.914.14
205KLIST shuffle1-s llength 1001.000.830.780.790.900.865.13
206KLIST shuffle1-s llength 10001.000.961.081.080.950.935.21
207KLIST shuffle1a llength 11.000.811.151.301.300.975.19
208KLIST shuffle1a llength 101.000.810.640.760.880.844.84
209KLIST shuffle1a llength 1001.000.830.640.730.880.857.27
210KLIST shuffle1a llength 10001.000.810.640.720.880.8424.65
211KLIST shuffle1a llength 100001.000.820.640.730.870.85-=-
212KLIST shuffle2 llength 11.000.861.051.411.411.694.51
213KLIST shuffle2 llength 101.000.860.560.710.711.052.78
214KLIST shuffle2 llength 1001.000.850.520.650.640.942.58
215KLIST shuffle2 llength 10001.000.890.510.640.630.922.54
216KLIST shuffle2 llength 100001.000.850.530.640.640.96-=-
217KLIST shuffle3 llength 11.000.801.211.481.851.484.43
218KLIST shuffle3 llength 101.000.770.600.840.950.954.36
219KLIST shuffle3 llength 1001.000.780.590.790.890.845.29
220KLIST shuffle3 llength 10001.000.780.590.870.980.9210.85
221KLIST shuffle3 llength 100001.000.840.711.421.511.45-=-
222KLIST shuffle4 llength 11.000.801.201.791.791.434.66
223KLIST shuffle4 llength 101.000.800.630.870.980.984.62
224KLIST shuffle4 llength 1001.000.800.610.850.940.916.57
225KLIST shuffle4 llength 10001.000.790.600.840.930.9017.96
226KLIST shuffle4 llength 100001.000.790.600.830.930.91-=-
227KLIST shuffle5-s llength 11.000.760.650.980.980.494.39
228KLIST shuffle5-s llength 101.000.820.660.650.650.653.72
229KLIST shuffle5-s llength 1001.000.840.650.620.600.583.90
230KLIST shuffle5-s llength 10001.000.880.910.940.780.773.90
231KLIST shuffle5a llength 11.000.750.650.790.790.794.33
232KLIST shuffle5a llength 101.000.810.530.550.550.553.95
233KLIST shuffle5a llength 1001.000.790.510.550.520.524.57
234KLIST shuffle5a llength 10001.000.810.530.650.620.628.10
235KLIST shuffle5a llength 100001.000.880.661.271.261.26-=-
236KLIST shuffle6 llength 11.000.850.85-=--=--=--=-
237KLIST shuffle6 llength 101.000.870.71-=--=--=--=-
238KLIST shuffle6 llength 1001.000.860.67-=--=--=--=-
239KLIST shuffle6 llength 10001.000.870.66-=--=--=--=-
240KLIST shuffle6 llength 100001.000.860.67-=--=--=--=-
241LIST append to list1.000.940.600.910.910.910.91
242LIST concat APPEND 2x101.000.900.890.770.770.770.31
243LIST concat APPEND 2x1001.000.960.900.870.820.800.12
244LIST concat APPEND 2x10001.001.020.920.870.880.860.08
245LIST concat APPEND 2x100001.001.020.940.880.870.860.08
246LIST concat CONCAT 2x101.000.800.860.753.013.011.50
247LIST concat CONCAT 2x1001.000.900.911.0717.1116.583.21
248LIST concat CONCAT 2x10001.000.981.000.9334.5333.723.84
249LIST concat CONCAT 2x100001.001.000.991.0037.6937.203.88
250LIST concat EVAL/LAPPEND 2x101.000.821.250.931.851.851.85
251LIST concat EVAL/LAPPEND 2x1001.000.881.270.973.883.243.88
252LIST concat EVAL/LAPPEND 2x10001.000.991.340.994.254.466.23
253LIST concat EVAL/LAPPEND 2x100001.000.981.361.054.805.066.97
254LIST concat FOREACH/LAPPEND 2x101.000.710.711.501.501.502.25
255LIST concat FOREACH/LAPPEND 2x1001.000.660.521.431.611.371.85
256LIST concat FOREACH/LAPPEND 2x10001.000.680.531.591.671.521.86
257LIST concat FOREACH/LAPPEND 2x100001.000.730.561.691.781.611.98
258LIST concat SET 2x101.000.971.040.810.810.810.40
259LIST concat SET 2x1001.001.010.910.850.850.820.16
260LIST concat SET 2x10001.001.030.920.850.840.830.09
261LIST concat SET 2x100001.001.020.910.840.840.830.08
262LIST exact search, first item1.000.800.350.000.000.0022.92
263LIST exact search, last item1.000.920.680.690.690.6911.46
264LIST exact search, middle item1.000.820.500.510.510.5117.17
265LIST exact search, non-item1.000.960.860.740.740.746.70
266LIST exact search, typed item1.000.850.550.530.530.538.97
267LIST exact search, untyped item1.000.920.700.710.710.7112.01
268LIST index first element1.000.750.420.000.000.003.26
269LIST index last element1.000.760.410.000.000.006.45
270LIST index middle element1.000.720.410.000.000.004.30
271LIST insert an item at "end"1.000.960.850.770.770.774.04
272LIST insert an item at middle1.000.940.880.950.950.951.15
273LIST insert an item at start1.000.960.900.970.970.970.77
274LIST iterate list1.000.901.313.223.083.49282.36
275LIST join list1.000.970.941.041.070.732.25
276LIST large, early range1.000.900.520.540.540.543.23
277LIST large, late range1.000.880.530.550.550.553.85
278LIST length, pure list1.000.730.610.000.000.0056.25
279LIST list1.000.870.500.690.690.692.07
280LIST lset foreach l1.000.180.16=8.4=8.4=8.4=8.4
281LIST lset foreach list1.000.170.16=8.4=8.4=8.4=8.4
282LIST lset foreach ""s l1.000.891.09=8.4=8.4=8.4=8.4
283LIST lset foreach ""s list1.000.891.05=8.4=8.4=8.4=8.4
284LIST regexp search, first item1.000.800.700.650.650.6521.43
285LIST regexp search, last item1.000.966.807.287.471.284.42
286LIST regexp search, non-item1.000.977.428.078.391.192.74
287LIST remove first element1.000.950.941.021.021.020.81
288LIST remove in mixed list1.000.941.001.0233.541.021.22
289LIST remove last element1.000.950.921.011.011.011.61
290LIST remove middle element1.000.950.921.011.011.011.21
291LIST replace first el with multiple1.000.970.890.950.950.951.13
292LIST replace first element1.000.940.820.750.750.750.94
293LIST replace in mixed list1.000.940.900.9531.240.951.14
294LIST replace last el with multiple1.000.980.800.720.900.724.12
295LIST replace last element1.000.950.790.730.730.734.00
296LIST replace middle el with multiple1.000.980.840.910.910.912.55
297LIST replace middle element1.000.950.800.740.740.742.58
298LIST replace range1.000.842.232.032.032.038.63
299LIST reverse core1.001.008.5+8.5+8.5+8.5+8.5+
300LIST reverse lappend1.000.961.353.813.813.6598.80
301LIST small, early range1.000.890.520.670.670.672.67
302LIST small, late range1.000.880.500.650.650.654.52
303LIST sort1.001.001.661.601.621.632.41
304LIST sorted search, first item1.000.760.360.000.000.0020.89
305LIST sorted search, last item1.000.770.371.291.291.2921.94
306LIST sorted search, middle item1.000.790.370.640.640.6421.15
307LIST sorted search, non-item1.000.780.372.582.582.5823.23
308LIST sorted search, typed item1.000.820.301.031.031.0317.44
309LIST typed sort1.000.971.811.811.861.793.84
310LOOP for (to 1000)1.001.040.932.302.272.4516.19
311LOOP for, iterate list1.000.931.342.312.212.33100.34
312LOOP for, iterate string1.000.951.071.751.861.718.43
313LOOP foreach, iterate list1.000.900.671.000.991.093.09
314LOOP foreach, iterate string1.000.960.690.952.072.102.41
315LOOP while (to 1000)1.000.940.922.292.242.3815.99
316LOOP while 1 (to 1000)1.000.890.822.012.362.5018.36
317MAP ([chars])-case regsub1.001.010.890.880.810.200.34
318MAP http mapReply1.001.030.861.000.990.900.64
319MAP regsub -nocase, no match1.001.051.031.571.570.810.79
320MAP regsub 1 val1.002.222.117.887.881.402.67
321MAP regsub 1 val -nocase1.001.511.473.333.320.871.28
322MAP regsub 2 val1.002.242.2616.0815.731.382.38
323MAP regsub 2 val -nocase1.001.631.597.897.860.941.43
324MAP regsub 3 val1.002.452.3816.9316.841.422.35
325MAP regsub 3 val -nocase1.001.701.658.018.040.951.42
326MAP regsub 4 val1.002.562.4717.2217.271.452.38
327MAP regsub 4 val -nocase1.001.751.678.078.080.951.42
328MAP regsub short1.000.970.521.771.770.511.52
329MAP regsub, no match1.001.091.126.997.672.041.93
330MAP string -nocase, no match1.001.181.207.807.73nomapnomap
331MAP string 1 val1.001.791.757.287.89nomapnomap
332MAP string 1 val -nocase1.001.401.326.377.52nomapnomap
333MAP string 2 val1.001.461.413.223.22nomapnomap
334MAP string 2 val -nocase1.001.271.264.584.77nomapnomap
335MAP string 3 val1.001.181.122.862.44nomapnomap
336MAP string 3 val -nocase1.001.221.236.495.45nomapnomap
337MAP string 4 val1.001.261.172.552.57nomapnomap
338MAP string 4 val -nocase1.001.331.326.707.22nomapnomap
339MAP string short1.000.970.480.590.59nomapnomap
340MAP string, no match1.001.401.295.265.16nomapnomap
341MAP |-case regsub1.000.990.770.720.830.210.41
342MAP |-case strmap1.000.880.500.550.55nomapnomap
343MATRIX mult 5x51.000.950.781.241.241.266.51
344MATRIX mult 10x101.000.990.771.201.171.237.40
345MATRIX mult 15x151.000.980.771.171.131.218.00
346MATRIX transposition-01.000.850.661.621.611.563.89
347MATRIX transposition-11.000.971.303.032.902.8629.68
348MD5 msg len 101.000.830.730.760.74-=--=-
349MD5 msg len 1001.000.900.780.830.81-=--=-
350MD5 msg len 10001.000.900.540.580.56-=--=-
351MD5 msg len 100001.000.940.190.200.19-=--=-
352MTHD array stored proc call1.000.770.360.000.000.00-=-
353MTHD call absolute1.000.870.500.610.610.61-=-
354MTHD call relative1.000.860.590.540.540.54-=-
355MTHD direct ns proc call1.000.770.360.000.000.00-=-
356MTHD imported ns proc call1.000.700.340.000.000.00-=-
357MTHD indirect proc eval1.000.880.560.370.751.12-=-
358MTHD indirect proc eval #21.000.871.261.321.321.32-=-
359MTHD inline call1.000.790.680.000.000.00-=-
360MTHD interp alias proc call1.000.600.330.960.960.00-=-
361MTHD ns lookup call1.000.850.600.620.770.93-=-
362MTHD switch method call1.000.900.640.681.021.36-=-
363NS alternating1.000.850.510.530.510.30-=-
364PARSE html form upload (7978)1.000.850.781.021.030.83-=-
365PARSE html form upload (993570)1.000.830.750.950.970.89-=-
366PROC do-nothing, no args1.000.740.490.002.330.000.00
367PROC do-nothing, one arg1.000.780.360.000.000.000.00
368PROC empty, no args1.000.730.450.009.090.009.09
369PROC empty, use args1.000.730.450.000.000.009.09
370PROC explicit return1.000.770.340.000.000.001.41
371PROC explicit return (2)1.000.780.390.000.000.001.49
372PROC explicit return (3)1.000.830.370.000.000.001.54
373PROC heavily commented1.000.790.360.000.000.0033.33
374PROC implicit return1.000.820.390.000.000.001.41
375PROC implicit return (2)1.000.790.450.000.000.001.49
376PROC implicit return (3)1.000.790.360.000.000.000.00
377PROC local links with global1.000.982.142.482.482.4813.20
378PROC local links with upvar1.000.971.912.192.242.2913.33
379PROC local links with variable1.000.931.671.991.991.0513.51
380RE 1-char long-end1.000.950.961.021.0214.4715.23
381RE 1-char long-end catching1.000.980.811.121.007.627.74
382RE 1-char long-middle1.000.880.900.770.7711.1511.92
383RE 1-char long-middle catching1.000.980.771.061.064.835.13
384RE 1-char long-start1.000.840.880.930.930.931.85
385RE 1-char long-start catching1.000.970.710.970.970.780.97
386RE 1-char short1.000.860.880.940.940.941.89
387RE 1-char short catching1.000.980.721.160.970.770.97
388RE basic1.000.840.881.041.041.042.08
389RE basic catching1.001.160.691.011.010.670.84
390RE c-comment long1.000.980.991.001.001.391.59
391RE c-comment long catching1.000.970.891.030.970.570.80
392RE c-comment long nomatch1.000.970.970.950.950.270.54
393RE c-comment long nomatch catching1.000.960.800.770.770.330.55
394RE c-comment long pmatch1.000.970.990.990.995.205.45
395RE c-comment long pmatch catching1.000.950.810.800.804.204.70
396RE c-comment many *s1.000.990.990.980.981.591.71
397RE c-comment many *s catching1.000.980.930.990.990.580.91
398RE c-comment nomatch1.000.870.890.530.530.530.53
399RE c-comment nomatch catching1.000.940.540.600.600.300.60
400RE c-comment simple1.000.930.951.051.050.700.70
401RE c-comment simple catching1.000.990.871.021.020.370.44
402RE count all matches1.000.960.880.852.342.024.37
403RE extract all matches1.001.040.920.922.342.014.60
404RE ini file1.001.011.001.001.000.010.01
405RE ini file ng1.000.990.951.001.00-=--=-
406RE literal regexp1.000.850.851.031.030.520.52
407RE n-char long-end1.000.920.961.011.0115.1115.62
408RE n-char long-end catching1.000.960.831.021.027.287.96
409RE n-char long-middle1.000.960.960.800.8012.0513.25
410RE n-char long-middle catching1.001.000.791.110.974.705.12
411RE n-char long-start1.000.840.890.890.890.891.79
412RE n-char long-start catching1.000.960.751.011.010.681.01
413RE n-char short1.000.830.870.880.880.881.77
414RE n-char short catching1.000.960.731.051.050.700.87
415RE static anchored match1.000.770.361.451.450.001.45
416RE static anchored match dot1.000.761.761.351.350.001.35
417RE static anchored nomatch1.000.770.361.371.370.001.37
418RE static anchored nomatch dot1.000.740.811.371.370.001.37
419RE static l-anchored match1.000.800.401.431.430.001.43
420RE static l-anchored nomatch1.000.770.371.430.000.001.43
421RE static long match1.000.860.782.522.521.682.52
422RE static long nomatch1.000.880.832.652.651.321.99
423RE static r-anchored match1.000.770.381.351.350.001.35
424RE static r-anchored nomatch1.000.750.381.301.300.001.30
425RE static short match1.000.760.401.331.330.001.33
426RE static short nomatch1.000.760.361.351.350.001.35
427RE var ***= directive match1.001.011.892.172.17-=--=-
428RE var ***= directive nomatch1.000.981.892.112.11-=--=-
429RE var . match1.000.751.141.301.301.302.60
430RE var [0-9] match1.000.890.940.610.611.842.45
431RE var \d match1.000.900.940.620.621.852.47
432RE var ^$ nomatch1.000.730.971.331.331.332.67
433RE var backtrack case1.001.020.090.110.111.461.51
434RE var-based regexp1.000.911.031.081.080.541.08
435READ 595K, cat1.000.890.691.231.040.470.68
436READ 595K, gets1.000.900.601.321.060.550.86
437READ 595K, glob-grep match1.000.990.701.121.040.680.96
438READ 595K, glob-grep nomatch1.000.980.731.411.330.760.99
439READ 595K, read1.001.020.941.871.8714.3414.27
440READ 595K, read & size1.001.010.921.851.840.6814.07
441READ 595K, read dyn buf1.001.020.931.848.3+8.3+8.3+
442READ 595K, read small buf1.000.980.980.998.3+8.3+8.3+
443READ 3050b, cat1.000.920.751.120.980.540.71
444READ 3050b, gets1.000.940.651.251.040.610.91
445READ 3050b, glob-grep match1.000.900.691.040.970.660.93
446READ 3050b, glob-grep nomatch1.000.940.751.331.270.800.99
447READ 3050b, read1.001.050.921.361.330.810.96
448READ 3050b, read & size1.001.000.841.281.250.780.94
449READ 3050b, read dyn buf1.000.990.871.198.3+8.3+8.3+
450READ 3050b, read small buf1.000.990.981.018.3+8.3+8.3+
451READ bin 595K, cat1.000.881.331.661.470.640.93
452READ bin 595K, gets1.000.880.861.581.320.751.16
453READ bin 595K, glob-grep match1.000.871.171.721.651.101.58
454READ bin 595K, glob-grep nomatch1.000.931.242.182.121.321.68
455READ bin 595K, read1.001.040.820.840.8058.3458.42
456READ bin 595K, read & size1.001.020.810.840.802.7457.24
457READ bin 595K, read dyn buf1.001.020.820.808.3+8.3+8.3+
458READ bin 595K, read small buf1.000.981.010.988.3+8.3+8.3+
459READ bin 3050b, cat1.000.941.211.441.330.700.90
460READ bin 3050b, gets1.000.920.871.421.210.771.10
461READ bin 3050b, glob-grep match1.000.920.741.000.970.660.92
462READ bin 3050b, glob-grep nomatch1.000.870.721.141.140.720.91
463READ bin 3050b, read1.000.960.840.820.820.981.07
464READ bin 3050b, read & size1.000.960.770.850.780.951.02
465READ bin 3050b, read dyn buf1.000.940.770.768.3+8.3+8.3+
466READ bin 3050b, read small buf1.000.991.000.998.3+8.3+8.3+
467SHA (A) msg len 101.000.910.921.191.22-=--=-
468SHA (A) msg len 1001.000.880.961.261.26-=--=-
469SHA (A) msg len 10001.000.870.991.321.32-=--=-
470SHA (A) msg len 100001.000.870.981.321.32-=--=-
471SHA (B) msg len 10-=--=-154.18201.00200.00-=--=-
472SHA (B) msg len 100-=--=-271.95361.00359.00-=--=-
473SHA (B) msg len 1000-=--=-1909.822621.002594.00-=--=-
474SHA (B) msg len 10000-=--=-18429.0025162.0025124.00-=--=-
475SPLIT iter, 4000 uchars1.000.920.700.911.861.832.15
476SPLIT iter, 4010 chars1.000.910.690.901.881.882.16
477SPLIT iter, rand 100 c1.000.990.900.870.600.57-=-
478SPLIT iter, rand 1000 c1.000.960.850.931.151.10-=-
479SPLIT iter, rand 10000 c1.000.930.800.961.851.79-=-
480SPLIT on 'c', 4000 uchars1.000.990.861.661.640.942.41
481SPLIT on 'c', 4010 chars1.000.990.851.591.590.962.12
482SPLIT on 'cz', 4000 uchars1.001.050.911.171.150.761.46
483SPLIT on 'cz', 4010 chars1.001.040.921.221.210.811.45
484SPLIT on 'cû', 4000 uchars1.001.020.901.071.060.681.34
485SPLIT on 'cû', 4010 chars1.001.020.921.171.130.641.34
486SPLIT, 4000 uchars1.000.940.790.713.593.390.68
487SPLIT, 4010 chars1.000.940.760.663.853.770.67
488SPLIT, rand 100 c1.001.000.910.830.500.47-=-
489SPLIT, rand 1000 c1.000.990.950.851.241.13-=-
490SPLIT, rand 10000 c1.000.960.920.823.403.09-=-
491STR append1.000.960.730.860.860.863.43
492STR append (1KB + 1KB)1.000.890.701.151.151.154.02
493STR append (1MB + (1b+1K+1b)*100)1.001.050.920.710.710.695.85
494STR append (1MB + 1KB)1.001.021.010.210.220.212.10
495STR append (1MB + 1KB*20)1.001.000.980.210.210.212.02
496STR append (1MB + 1KB*1000)1.001.021.000.330.330.331.87
497STR append (1MB + 1MB*3)1.001.010.960.900.900.903.10
498STR append (1MB + 1MB*5)1.001.051.001.251.281.322.62
499STR append (1MB + 2b*1000)1.001.121.082.592.632.5413.09
500STR append (10KB + 1KB)1.000.921.031.491.491.495.94
501STR first (failure)1.000.700.751.021.021.021.18
502STR first (failure) utf1.000.700.752.212.211.021.19
503STR first (success)1.000.700.280.520.520.001.57
504STR first (success) utf1.000.720.280.530.530.001.60
505STR first (total failure)1.000.870.680.930.930.931.62
506STR first (total failure) utf1.000.870.681.161.160.931.62
507STR index 01.000.750.671.151.151.153.45
508STR index 1001.000.750.671.151.151.153.45
509STR index 5001.000.720.671.141.141.143.41
510STR info locals match1.000.971.191.521.561.479.06
511STR last (failure)1.000.880.940.810.810.611.42
512STR last (success)1.000.730.275.675.670.003.61
513STR last (total failure)1.000.860.670.680.680.681.36
514STR length (==4010)1.000.690.630.000.000.005.08
515STR length growing (1000)1.000.740.722.242.312.397.07
516STR length growing uc (1000)1.000.740.732.232.292.237.13
517STR length of a LIST1.000.760.590.000.000.005.17
518STR length static str1.000.840.381.451.451.452.90
519STR match, complex (failure)1.001.181.119.759.964.154.77
520STR match, complex (success early)1.000.730.410.960.960.962.88
521STR match, complex (success late)1.000.910.866.926.923.123.39
522STR match, complex (total failure)1.000.900.8113.4713.475.736.59
523STR match, exact (failure)1.000.780.380.000.000.001.45
524STR match, exact (success)1.000.780.360.000.000.001.45
525STR match, exact -nocase (failure)1.000.790.390.000.001.431.43
526STR match, exact -nocase (success)1.000.820.501.221.221.221.22
527STR match, recurse (fail backtrack)1.000.980.946.876.954.408.56
528STR match, recurse (fail bt1)1.000.990.956.896.974.488.44
529STR match, recurse (fail bt2)1.000.980.946.836.974.488.43
530STR match, recurse (fail ranchor)1.001.001.0018.3318.367.717.73
531STR match, recurse (success bt2)1.000.890.720.701.267.8727.39
532STR match, recurse2 (fail)1.001.261.2611.8611.854.994.99
533STR match, recurse2 (success)1.001.181.119.719.714.134.75
534STR match, simple (failure)1.000.870.260.000.000.000.94
535STR match, simple (success)1.000.750.320.000.000.001.09
536STR range, index 100..200 of 40101.000.880.370.430.430.431.73
537STR repeat, 4010 chars * 101.000.830.610.571.152.018.91
538STR repeat, 4010 chars * 1001.000.940.870.852.293.2110.12
539STR repeat, abcdefghij * 101.000.780.250.000.461.836.42
540STR repeat, abcdefghij * 1001.000.850.510.371.1210.4538.43
541STR repeat, abcdefghij * 10001.000.981.100.982.4632.72123.00
542STR replace, equal replacement1.000.870.413.313.580.282.20
543STR replace, longer replacement1.000.870.453.303.300.272.20
544STR replace, no replacement1.000.830.383.934.260.332.62
545STR reverse core, 10 c1.000.668.5+8.5+8.5+8.5+8.5+
546STR reverse core, 10 uc1.000.768.5+8.5+8.5+8.5+8.5+
547STR reverse core, 100 c1.000.688.5+8.5+8.5+8.5+8.5+
548STR reverse core, 100 uc1.000.748.5+8.5+8.5+8.5+8.5+
549STR reverse core, 400 c1.000.768.5+8.5+8.5+8.5+8.5+
550STR reverse core, 400 uc1.000.798.5+8.5+8.5+8.5+8.5+
551STR reverse iter/append, 10 c1.000.920.941.821.821.823.95
552STR reverse iter/append, 10 uc1.000.930.931.821.821.823.94
553STR reverse iter/append, 100 c1.000.920.882.392.252.204.93
554STR reverse iter/append, 100 uc1.000.950.912.282.232.144.80
555STR reverse iter/append, 400 c1.000.980.882.432.392.326.82
556STR reverse iter/append, 400 uc1.001.020.912.392.352.266.65
557STR reverse iter/set, 10 c1.000.940.861.251.251.252.92
558STR reverse iter/set, 10 uc1.000.950.881.041.041.252.92
559STR reverse iter/set, 100 c1.000.990.911.241.241.172.86
560STR reverse iter/set, 100 uc1.000.980.941.241.221.142.81
561STR reverse iter/set, 400 c1.000.960.951.291.221.183.93
562STR reverse iter/set, 400 uc1.000.991.001.311.251.173.95
563STR reverse recursive, 10 c1.000.870.450.550.510.431.06
564STR reverse recursive, 10 uc1.000.890.430.580.540.461.12
565STR reverse recursive, 100 c1.000.920.470.560.550.481.06
566STR reverse recursive, 100 uc1.000.870.450.740.720.481.06
567STR reverse recursive, 400 c1.000.850.460.540.530.488.0+
568STR reverse recursive, 400 uc1.000.800.431.111.100.498.0+
569STR str $a eq $b1.000.780.651.081.081.084.30
570STR str $a eq $b (same obj)1.000.740.661.021.021.024.08
571STR str $a equal ""1.000.760.411.051.051.055.26
572STR str $a ne $b1.000.770.671.031.032.064.12
573STR str $a ne $b (same obj)1.000.860.691.161.161.164.65
574STR str num == ""1.000.800.441.051.051.055.26
575STR strcmp bin long eq1.000.810.5710.9810.98-=--=-
576STR strcmp bin long neq1.000.870.5510.3710.37-=--=-
577STR strcmp bin long neqS1.000.770.3214.4014.40-=--=-
578STR strcmp bin short eq1.000.740.280.570.57-=--=-
579STR streq bin long eq1.0012.4711.9610.9810.67-=--=-
580STR streq bin long neq1.0011.9911.4610.1210.22-=--=-
581STR streq bin long neqS1.0016.6816.0214.0514.05-=--=-
582STR streq bin short eq1.001.010.550.550.55-=--=-
583STR string compare1.000.780.711.161.161.162.33
584STR string compare ""1.000.820.550.990.990.992.97
585STR string compare long1.000.900.931.311.311.314.80
586STR string compare long (same obj)1.000.790.742.562.562.5614.10
587STR string compare mixed long1.000.990.980.190.190.130.63
588STR string compare uni long1.000.990.980.190.130.130.65
589STR string equal ""1.000.750.470.980.980.983.92
590STR string equal long (!= len)1.000.740.702.272.272.2710.61
591STR string equal long (== len)1.000.980.971.201.201.205.62
592STR string equal long (same obj)1.000.760.693.093.093.0914.43
593STR string equal mixed long1.000.770.653.003.003.0014.00
594STR string equal uni long1.000.710.690.790.790.793.70
595STR/LIST length, obj shimmer1.001.030.920.900.910.010.20
596SWITCH 1st true1.000.811.621.161.161.165.81
597SWITCH 2nd true1.000.801.661.121.121.125.62
598SWITCH 9th true1.000.811.901.161.162.335.81
599SWITCH default true1.000.821.941.221.222.446.10
600TRACE all set (rwu)1.001.540.980.750.750.752.24
601TRACE no trace set1.001.570.940.690.690.692.08
602TRACE read1.001.650.980.750.750.752.26
603TRACE unset1.001.590.890.740.740.742.21
604TRACE write1.001.500.920.750.750.752.26
605UNSET catch var !exist1.000.910.330.230.340.230.23
606UNSET catch var exists1.001.350.670.000.000.001.33
607UNSET info check var !exist1.000.810.560.000.000.001.30
608UNSET info check var exists1.001.360.771.301.301.301.30
609UNSET nocomplain var !exist1.001.850.572.782.782.782.78
610UNSET nocomplain var exists1.002.060.580.000.000.001.45
611UNSET var exists1.001.520.540.000.000.001.41
612UPLEVEL none1.001.000.681.211.261.29-=-
613UPLEVEL primed1.001.044.304.050.630.66-=-
614UPLEVEL to nseval1.000.793.012.420.450.48-=-
615UPLEVEL to proc1.000.883.282.950.490.47-=-
616VAR 'array set' of 100 elems1.000.890.871.441.441.312.88
617VAR 100 'set's in array1.000.900.870.900.901.083.24
618VAR access global1.000.810.610.940.940.942.83
619VAR access local proc arg1.000.800.410.000.000.003.61
620VAR access locally set1.000.790.420.000.000.003.49
621VAR access upvar1.000.800.580.920.920.922.75
622VAR incr global var 1000x1.000.970.701.521.501.639.92
623VAR incr local var 1000x1.001.000.721.551.521.6710.15
624VAR incr upvar var 1000x1.000.950.711.571.531.6510.08
625VAR mset1.000.901.251.691.691.6911.86
626VAR mset (foreach)1.000.790.710.000.000.007.58
627VAR ref absolute1.000.900.540.730.730.678.0+
628VAR ref local1.000.851.012.081.732.088.0+
629VAR ref variable1.000.831.033.774.093.468.0+
630VAR set array element1.000.790.550.000.000.001.03
631VAR set scalar1.000.810.460.000.000.001.43
632WORDCOUNT wc11.000.960.820.880.840.430.54
633WORDCOUNT wc21.000.970.891.481.550.931.05
634WORDCOUNT wc31.000.970.851.501.560.930.86
634BENCHMARKS1:8.6b1.22:8.5.93:8.4.194:8.3.55:8.2.36:8.0.57:7.6p2
 FINISHED 2010-09-27 19:59:24

JH: The numbers below by Kevin are for a previous set of numbers, and need updating (note only 8.4a3 is mentioned). The only thing likely to change though is to show that 8.4 is pulling ahead in performance.

Kevin Kenny: For those that insist on a single figure of merit, I took these numbers, normalized them to a scale of 8.4a3 == 1.0, and then took the harmonic mean of all benchmarks.

Version Relative Speed Comments
7.6p2 0.125 The last version without bytecode compilation
8.0.5 0.736 Bytecode compilation initially sped things up by a factor of about 6.
8.2.3 0.600 The cost of internationalization was that things got about 20% slower.
8.3.1 0.606 Not much change here...
8.4a3 1.000 The reference against which the others were measured. Many more operations are bytecoded, which gains about 50% in speed.
8.5.? ????? Much more bytecoding, but many operations slowed down to support new features (especially clock and arbitrary-width integers).

As with all benchmarks, take these numbers with a spoonful of salt!


TCL benchmarks compared with other languages