当从具有变量名称的变量获取变量值时,tcl 的 subst 似乎比 set 慢
tcl's subst seems slower than set, when getting a variable value from a variable with a variable's name
参见下面的 Tcl 8.4 代码和下面的 shell 输出:(我需要元编码):
% set k a
% set m k
% puts [set $m ]
a
% puts [subst $$m]
a
因此,看来 set $m
和 subst $$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。我们能否期望在未来的版本中保持这种情况?
谢谢
你可以期待一切都保持原样。当您使用:
puts [set $m]
Tcl 将编译一次读取 m
变量(将结果存储在内部操作堆栈中),读取其名称在操作堆栈中的变量,然后调用 puts
结果。
当你这样做时:
puts [subst $$m]
Tcl 将其编译为 $
的串联和读取 m
的结果,调用替换引擎(反过来将解析和字节码编译该片段)然后才puts
的结果。哪个更复杂。
如果你这样做,你会看到不同之处:
set m {k[exit]}
第一个只会告诉您您正在尝试从一个不存在的(奇怪命名的)变量中读取。第二个将退出进程。
参见下面的 Tcl 8.4 代码和下面的 shell 输出:(我需要元编码):
% set k a
% set m k
% puts [set $m ]
a
% puts [subst $$m]
a
因此,看来 set $m
和 subst $$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。我们能否期望在未来的版本中保持这种情况?
谢谢
你可以期待一切都保持原样。当您使用:
puts [set $m]
Tcl 将编译一次读取 m
变量(将结果存储在内部操作堆栈中),读取其名称在操作堆栈中的变量,然后调用 puts
结果。
当你这样做时:
puts [subst $$m]
Tcl 将其编译为 $
的串联和读取 m
的结果,调用替换引擎(反过来将解析和字节码编译该片段)然后才puts
的结果。哪个更复杂。
如果你这样做,你会看到不同之处:
set m {k[exit]}
第一个只会告诉您您正在尝试从一个不存在的(奇怪命名的)变量中读取。第二个将退出进程。