【问题标题】:tcl's subst seems slower than set, when getting a variable value from a variable with a variable's name当从具有变量名称的变量中获取变量值时,tcl 的 subst 似乎比 set 慢
【发布时间】:2016-06-08 10:28:51
【问题描述】:

参见下面的 Tcl 8.4 代码和下面的 shell 输出:(我需要元编码):

% set k a
% set m k
% puts [set $m ]
a
% puts [subst $$m]
a

因此,set $msubst $$m 似乎具有相同的功能。但是,运行时(在简单的测试用例中)是相当不同的(请参阅下面的 shell 结果的延续:

% time { set $m } 1000000
0.256435 microseconds per iteration
% time { subst $$m } 1000000
0.627714 microseconds per iteration

可以看出,set 比 subst 快约 2.5。 2个问题是: 待问: 1. 为什么?
2. 我已经看到它在 Tcl 8.5 中快了 ~3.6。我们能否期望在未来的版本中保持这种情况?
谢谢

【问题讨论】:

  • 让我们正确看待这一点:我们所说的时间不到一微秒。
  • 是的。但是,如果您必须这样做数亿次,会发生什么?
  • 嗯,每次迭代半微秒乘以 5 亿次迭代大约是 4 分钟。当然值得一看,但可能不是你最大的瓶颈。
  • 不。但是这段代码可能会在以后被使用,在被访问数十亿次的东西(VLSI 芯片晶体管)上运行很多次,在昂贵的许可 EDA 软件上,它开始显现出来。

标签: performance variables runtime tcl


【解决方案1】:

您可以期望事情保持不变。使用时:

puts [set $m]

Tcl 将编译一次以读取 m 变量(将结果存储在内部操作堆栈上)读取名称在操作堆栈上的变量,然后调用 puts 并使用结果。

当你这样做时:

puts [subst $$m]

Tcl 将其编译为$ 的串联和读取m 的结果,调用替换引擎(依次解析和字节码编译该片段),然后才得到结果的puts .哪个更复杂。

如果你这样做了,你会看到不同的:

set m {k[exit]}

第一个只会告诉你你试图从一个不存在的(奇怪命名的)变量中读取。第二个将退出该过程。

【讨论】:

  • 实际上,Tcl 8.6 中的速度差异将大于 8.5 中的速度差异,因为非常量字符串的subst 在那里受到了性能影响。另一方面,constant 字符串的subst 获得了性能提升。 (它源于非递归评估引擎的启用方式。)
  • 指定 -nocommands 和 -nobackslashes 是否有助于提高性能?
  • @glennjackman 可能不是很多;这只是改变了对[\ 的响应,但它们仍然需要被解析(因为我们现在不交换解析器)。除了两种情况下都需要的变量查找之外,您仍然需要使用 subst(在 8.6 中生成字节码)进行额外的解析。如果使用动态变量名,通常最好将它们upvar 0 设置为固定的本地别名……
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-24
  • 1970-01-01
  • 2014-02-08
  • 2021-11-17
  • 2022-01-23
相关资源
最近更新 更多