tcl 非花括号表达式比用它们慢?
tcl non curly braces expression slower than with them?
我注意到了一些事情。让我们看看两个代码位。在1中,如果不是用花括号输入,另一个是。大括号 1 稍快一些。为什么?
请参阅下面的代码和输出:
puts [ time { if { [ expr { 5 % 2 } ] } { puts 1 } else { puts 2 } } ]
1
52 microseconds per iteration
puts [ time { if [ expr { 5 % 2 } ] { puts 1 } else { puts 2 } } ]
1
54 microseconds per iteration
差异稳定。使用更多代码字符时快 2 微秒。
为什么?
就像 expr
一样,支持 if
的 expr 使您的代码 faster/more 高效。基本上,没有大括号,我引用上面的 wiki link,expr 可能会经历意外的转换 numeric -> string -> numeric,你可能会失去精度,你的表达式将是慢得多,你甚至会遇到安全问题。
引用 a different wiki:
Question: Does the evaluation of expr1 by if differ from how expr
evaluates its arguments?
Answer: No, expr in if
is processed exactly the same as an argument to expr
DKF: They use the same parser and bytecode generator. Main difference is that expr concatenates its arguments before parsing, but if requires a single argument.
定时一次不是很有用:让它 运行 10000 次
将命令放入过程中:(删除内部 puts
命令以消除嘈杂的输出)
proc time_it {n} {
# bracing the command
puts [time {if {[expr {5%2}]} {expr 1} else {expr 2}} $n]
# unbraced
puts [time {if [expr {5%2}] {expr 1} else {expr 2}} $n]
# removing the unnecessary `expr` command altogether
puts [time {if {5%2} {expr 1} else {expr 2}} $n]
}
然后,运行一次,两次
% time_it 1
89 microseconds per iteration
27 microseconds per iteration
45 microseconds per iteration
% time_it 1
3 microseconds per iteration
8 microseconds per iteration
1 microseconds per iteration
我假设在第一个 运行 期间正在进行一些编译。在第 2 个 运行 期间,非支撑代码最慢。现在,在一系列迭代中计时。
% time_it 1000
0.27 microseconds per iteration
1.245 microseconds per iteration
0.267 microseconds per iteration
% time_it 10000
0.2823 microseconds per iteration
1.2491 microseconds per iteration
0.2198 microseconds per iteration
% time_it 100000
0.28989 microseconds per iteration
0.80064 microseconds per iteration
0.11543 microseconds per iteration
当你用大括号括起一个表达式时,尤其是当你在该表达式中使用可变部分时,Tcl 变得能够在脚本编译时确定表达式的语义是什么。这允许它为表达式生成字节码,并在实际 运行 编码代码时使一切变得更加快速。
如果没有大括号,编译器可能不得不回退到只发出编译指令和运行 运行 时的表达式。也就是说,它基本上推迟了真正的编译工作。显然,这并没有那么快,因为分析事物 永远不会 是免费的。 (它也可能有其他问题,例如允许安全问题。)
在您的具体示例中,差异不是很大。对于真实的脚本,如果您使用正确的大括号,它可以 轻松地 将它们 运行 的速度提高一倍或三倍。更快and更安全and还好写吗?有什么不喜欢的!
我注意到了一些事情。让我们看看两个代码位。在1中,如果不是用花括号输入,另一个是。大括号 1 稍快一些。为什么?
请参阅下面的代码和输出:
puts [ time { if { [ expr { 5 % 2 } ] } { puts 1 } else { puts 2 } } ]
1
52 microseconds per iteration
puts [ time { if [ expr { 5 % 2 } ] { puts 1 } else { puts 2 } } ]
1
54 microseconds per iteration
差异稳定。使用更多代码字符时快 2 微秒。
为什么?
就像 expr
一样,支持 if
的 expr 使您的代码 faster/more 高效。基本上,没有大括号,我引用上面的 wiki link,expr 可能会经历意外的转换 numeric -> string -> numeric,你可能会失去精度,你的表达式将是慢得多,你甚至会遇到安全问题。
引用 a different wiki:
Question: Does the evaluation of expr1 by if differ from how
expr
evaluates its arguments?Answer: No, expr in
if
is processed exactly the same as an argument toexpr
DKF: They use the same parser and bytecode generator. Main difference is that expr concatenates its arguments before parsing, but if requires a single argument.
定时一次不是很有用:让它 运行 10000 次
将命令放入过程中:(删除内部 puts
命令以消除嘈杂的输出)
proc time_it {n} {
# bracing the command
puts [time {if {[expr {5%2}]} {expr 1} else {expr 2}} $n]
# unbraced
puts [time {if [expr {5%2}] {expr 1} else {expr 2}} $n]
# removing the unnecessary `expr` command altogether
puts [time {if {5%2} {expr 1} else {expr 2}} $n]
}
然后,运行一次,两次
% time_it 1
89 microseconds per iteration
27 microseconds per iteration
45 microseconds per iteration
% time_it 1
3 microseconds per iteration
8 microseconds per iteration
1 microseconds per iteration
我假设在第一个 运行 期间正在进行一些编译。在第 2 个 运行 期间,非支撑代码最慢。现在,在一系列迭代中计时。
% time_it 1000
0.27 microseconds per iteration
1.245 microseconds per iteration
0.267 microseconds per iteration
% time_it 10000
0.2823 microseconds per iteration
1.2491 microseconds per iteration
0.2198 microseconds per iteration
% time_it 100000
0.28989 microseconds per iteration
0.80064 microseconds per iteration
0.11543 microseconds per iteration
当你用大括号括起一个表达式时,尤其是当你在该表达式中使用可变部分时,Tcl 变得能够在脚本编译时确定表达式的语义是什么。这允许它为表达式生成字节码,并在实际 运行 编码代码时使一切变得更加快速。
如果没有大括号,编译器可能不得不回退到只发出编译指令和运行 运行 时的表达式。也就是说,它基本上推迟了真正的编译工作。显然,这并没有那么快,因为分析事物 永远不会 是免费的。 (它也可能有其他问题,例如允许安全问题。)
在您的具体示例中,差异不是很大。对于真实的脚本,如果您使用正确的大括号,它可以 轻松地 将它们 运行 的速度提高一倍或三倍。更快and更安全and还好写吗?有什么不喜欢的!