Posted to tcl by dgp at Mon Apr 13 18:55:57 GMT 2015view pretty

Testing with current Tcl trunk...

# demo.tcl
# Call as: tclsh demo.tcl $length $copies $iters

lassign $argv length copies iters
proc demo {length copies} {
   set original {}
   for {set i 0} {$i<$length} {incr i} {
        lappend original [list [tcl::mathfunc::rand]]
   }
   for {set i 0} {$i<$copies} {incr i} {
      set copy {}
      foreach record $original {
         lappend copy [list [lindex $record 0]]
#         lappend copy $record
      }
      set original $copy
   }
}
for {set i 0} {$i<$iters} {incr i} {
    puts [time {demo $length $copies}]
}

$tclsh8.6 demo.tcl 10000 2000 8
6115335 microseconds per iteration
6491340 microseconds per iteration
7331890 microseconds per iteration
7902593 microseconds per iteration
7998689 microseconds per iteration
8280205 microseconds per iteration
8421163 microseconds per iteration
8749917 microseconds per iteration

Mystery is why does performance degrade?

Switch to the commented line in the inner loop 
and the degradation goes away:

$tclsh demo.tcl 10000 2000 8
2823475 microseconds per iteration
2867695 microseconds per iteration
2839149 microseconds per iteration
2887773 microseconds per iteration
2875267 microseconds per iteration
2883500 microseconds per iteration
2879356 microseconds per iteration
2891140 microseconds per iteration

Switch to a --disable-threads build, and
the degradation goes away:

$tclsh demo.tcl 10000 2000 8
6257281 microseconds per iteration
6218093 microseconds per iteration
6194935 microseconds per iteration
6193332 microseconds per iteration
6197974 microseconds per iteration
6233841 microseconds per iteration
6207849 microseconds per iteration
6217702 microseconds per iteration

My primary suspect is zippy, but other hypotheses are invited.

Why does this happen?  Does it happen for you too?