From: SourceForge.net <no...@so...> - 2003-08-05 08:44:15
|
Bugs item #781585, was opened at 2003-08-01 17:22 Message generated for change (Comment added) made by dkf You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=110894&aid=781585&group_id=10894 Category: 46. Bytecode Compiler Group: 8.4.4 Status: Open Resolution: None >Priority: 7 Submitted By: Franco Violi (effevi) Assigned to: miguel sofer (msofer) Summary: Interpreter 10 time slower then 8.3.3 Initial Comment: This small program show something wrong on 8.4.4 against 8.3.3. Try as is on 8.4.4 and the do the same uncommenting the append statement. #!/usr/bin/tngsh set buffout [string repeat x 3000000] proc goappend {} { global buffout switch x { x { append buffout "1" } } # # uncomment this line to see the code much more slower !! # # append buffout "x" # return 1 } for {set i 0} {$i < 3000} {incr i} { goappend puts "append $i" } ---------------------------------------------------------------------- >Comment By: Donal K. Fellows (dkf) Date: 2003-08-05 09:44 Message: Logged In: YES user_id=79902 Yuck-o! The extra reference is actually the interpreter result. :^/ Adding a Tcl_ResetResult(interp) to the INST_POP instruction (pick your own obvious spot) results in no (new) Tcl tests failing and the following (with Peter Spjuth's goappend) performance data: % set buffout [string repeat x 30000] ;puts [time {goappend 0} 5000] 15 microseconds per iteration % set buffout [string repeat x 30000] ;puts [time {goappend 1} 5000] 26 microseconds per iteration % set buffout [string repeat x 30000] ;puts [time {goappend 2} 5000] 22 microseconds per iteration I'm not sure what the overall performance implications of doing this are though, so perhaps a more focussed fix would be better? ---------------------------------------------------------------------- Comment By: Peter Spjuth (pspjuth) Date: 2003-08-05 01:20 Message: Logged In: YES user_id=98900 My theory is that there is a lingering object reference to the first append's result, causing an object duplication in the second append. By invoking any non byte compiled command between the appends, it works. proc goappend {w} { set append append if {$w == 0} { $append ::buffout x append ::buffout x } elseif {$w == 1} { $append ::buffout x string range a 0 0 append ::buffout x } else { $append ::buffout x string index a 0 append ::buffout x } } puts [info patch] set buffout [string repeat x 30000] puts [time {goappend 0} 5000] set buffout [string repeat x 30000] puts [time {goappend 1} 5000] set buffout [string repeat x 30000] puts [time {goappend 2} 5000] 8.5a0 249.5 microseconds per iteration 10.8 microseconds per iteration 244.5 microseconds per iteration ---------------------------------------------------------------------- Comment By: Donal K. Fellows (dkf) Date: 2003-08-05 01:17 Message: Logged In: YES user_id=79902 Bytecodes look reasonable. I'm out of my depth! ---------------------------------------------------------------------- Comment By: Donal K. Fellows (dkf) Date: 2003-08-05 00:48 Message: Logged In: YES user_id=79902 There's still something there in 8.4.4 though the overall performance is significantly better (or maybe the test machine is better :^/) % info patch 8.4.4 % proc goappend {w} { set appen append if {$w==0} { append ::buffout z;$appen ::buffout z } else { $appen ::buffout z;append ::buffout z } } % set buffout [string repeat x 50000];time {goappend 0} 10000 10 microseconds per iteration % set buffout [string repeat x 50000];time {goappend 1} 10000 261 microseconds per iteration ---------------------------------------------------------------------- Comment By: Jeffrey Hobbs (hobbs) Date: 2003-08-05 00:40 Message: Logged In: YES user_id=72656 On Win2K/P4 2.4ghz I get: (tkcon) 55 % time {set ::buffout ""; goappend 0} 2000 5 microseconds per iteration (tkcon) 55 % time {set ::buffout ""; goappend 1} 2000 6 microseconds per iteration and (tkcon) 58 % time {set ::buffout [string repeat x 5000]; goappend 0} 2000 238 microseconds per iteration (tkcon) 58 % time {set ::buffout [string repeat x 5000]; goappend 1} 2000 239 microseconds per iteration So unless a better example is provided, I don't see the issue. ---------------------------------------------------------------------- Comment By: Donal K. Fellows (dkf) Date: 2003-08-05 00:39 Message: Logged In: YES user_id=79902 Hmm. Minor error, but problem still there... % set buffout [string repeat x 5000];time {goappend 0} 1000 8 microseconds per iteration % set buffout [string repeat x 5000];time {goappend 1} 1000 157 microseconds per iteration ---------------------------------------------------------------------- Comment By: Donal K. Fellows (dkf) Date: 2003-08-05 00:33 Message: Logged In: YES user_id=79902 How bizarre can you get? proc goappend {w} { set appen append if {$w==0} { append ::buffout z;$appen ::buffout z } else { $appen ::buffout z;append ::buffout z } } puts [time {goappend 0} 2000] ;# => 7 microseconds puts [time {goappend 1} 2000] ;# => 892 microseconds ---------------------------------------------------------------------- Comment By: Donal K. Fellows (dkf) Date: 2003-08-04 23:56 Message: Logged In: YES user_id=79902 Behaviour looks linear in initial list size, and is not dependent on shimmering strings to append. :^( ---------------------------------------------------------------------- Comment By: Donal K. Fellows (dkf) Date: 2003-08-03 15:49 Message: Logged In: YES user_id=79902 Noting here that the specific example listed should go much faster in 8.5 where the mode will no longer be mixed (BCCed "switch" applies), not that that means we don't have a problem. ---------------------------------------------------------------------- Comment By: miguel sofer (msofer) Date: 2003-08-02 03:30 Message: Logged In: YES user_id=148712 Verified in 8.4.3 and 8.4.2 too. The following script isolates a bit the probable causes: - [switch] is innocent; what seems to cause the problem is that append is called "mixed" (once bytecompiled, once invoked) - it is not obvious that it is caused by the new variable tclObjTypes (but they remain a prime suspect tomy eyes) - [global] is innocent, although it is important that this a global variable. The behaviour is identical if we use [global buffout] instead of the fully qualified name ::buffout set buffout [string repeat x 300000] proc goappend {w} { set append append if {$w == 0} { $append ::buffout "1" $append ::buffout "1" } elseif {$w == 1} { $append ::buffout "1" append ::buffout "1" } else { append ::buffout "1" append ::buffout "1" } } puts [info patch] puts [time {goappend 0} 3000] puts [time {goappend 1} 3000] puts [time {goappend 2} 3000] Output: 8.4.3 13 microseconds per iteration 2273 microseconds per iteration 11 microseconds per iteration 8.4.2 8 microseconds per iteration 2231 microseconds per iteration 7 microseconds per iteration 8.3.4 13 microseconds per iteration 13 microseconds per iteration 12 microseconds per iteration ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=110894&aid=781585&group_id=10894 |