简体   繁体   中英

Tcl upvar and uplevel in performance

Let's say I have a variable which is one level up, which I just want to query its' value. I have two options:
uplevel { set var_name }
Or:
upvar var_name
If I need to query the variable just once, and not change it, which one should be faster?

You'll find that upvar is probably faster for this. Not necessarily, but most likely. (If you're worried about performance, time the alternatives.) Note that they will both necessarily have to resolve the variable name; that's a cost that's going to be borne anyway. But the version with upvar doesn't involve moving code between contexts, so it is likely to be faster.

FWIW, when I try with the example below, my intuition is correct. (The key is that one uses the upvar bytecode opcode; the other does invokeStk , which is slower because that's the general command dispatcher and has a bunch of overhead necessary for other purposes.)

% proc foo {y} {set x 1; bar $y}
% proc bar {y} {upvar 1 x x; list $x $y}
% foo 2
1 2
% time {foo 2} 10000
17.8188412 microseconds per iteration
% proc bar {y} {set x [uplevel 1 {set x}]; list $x $y}
% foo 2
1 2
% time {foo 2} 10000
25.4614022 microseconds per iteration

I prefer timerate for this kind of micro-benchmarking:

% namespace import ::tcl::unsupported::timerate
% timerate -calibrate {}
0.03257451263357219 µs/#-overhead 0.032807 µs/# 59499506 # 30481304 #/sec
% proc foo {y} {set x 1; bar $y}
% proc bar {y} {upvar 1 x x; list $x $y}
% timerate {foo 2} 10000
0.437240 µs/# 21285016 # 2287075 #/sec 9306.651 net-ms
% proc bar {y} {set x [uplevel 1 {set x}]; list $x $y}
% timerate {foo 2} 10000
0.612693 µs/# 15497439 # 1632137 #/sec 9495.179 net-ms

(Answer holds, clearly: Use upvar ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM