【问题标题】:Tcl upvar and uplevel in performanceTcl upvar 和 uplevel 的性能
【发布时间】:2021-06-18 18:53:36
【问题描述】:

假设我有一个上一级的变量,我只想查询它的值。我有两个选择:
uplevel { set var_name }
或:
upvar var_name
如果我只需要查询一次变量而不更改它,哪个应该更快?

【问题讨论】:

    标签: performance tcl upvar uplevel


    【解决方案1】:

    您会发现upvar 可能会更快。不一定,但很有可能。 (如果您担心性能,time 替代方案。) 请注意,它们都必须解析变量名;这是无论如何都要承担的成本。但是带有upvar 的版本不涉及在上下文之间移动代码,因此它可能会更快。

    FWIW,当我尝试下面的示例时,我的直觉是正确的。 (关键是一个使用upvar字节码操作码;另一个使用invokeStk,这比较慢,因为这是通用的命令调度程序,并且有很多其他用途所必需的开销。)

    % 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
    

    【讨论】:

      【解决方案2】:

      我更喜欢 timerate 进行这种微基准测试:

      % 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
      

      (答案显然成立:使用upvar)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-08-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-31
        • 1970-01-01
        相关资源
        最近更新 更多