我知道在某些动态的解释语言中,使用eval会减慢速度,因为它会停止字节编码。
在Tcl 8.5中是这样吗?
感谢
答案 0 :(得分:2)
它不会阻止字节码编译,但无论如何它都会减慢速度。关键问题是它可以防止字节码编译器在编译期间访问局部变量表(LVT),从而强制变量访问通过哈希查找。 Tcl有一个超快速的哈希算法(我们已经对它进行了很多基准测试并尝试了很多替代方案;它是非常热门代码)但是LVT有点击败,因为它只是一个简单的C数组查找字节在路上。只有在编译整个过程(或其他类似过程的事物,如lambda术语或TclOO方法)时才能正确地知道LVT。
现在,我尝试过这个具体案例:
eval {
# Do stuff in here...
}
完全是字节码编译的,它主要起作用(除了一些目前可观察但可能不应该的奇怪的东西)但是对于我们使用它的数量,它显然不值得。在任何其他情况下,在编译器运行时无法精确地知道脚本这一事实会强制执行无LVT操作模式。
另一方面,并非所有的悲观和悲观。如果在eval
内运行的实际脚本没有改变(并且包括不通过内部concat
重新生成 - 多参数eval
永远不会得到这个好处)Tcl可以在脚本值的内部表示中缓存代码的编译,尽管它是LVT-less,因此在那里仍然有相当多的性能提升。这意味着这不是太糟糕,表现明智:
set script {
foo bar $boo
}
for {set i 0} {$i < 10} {incr i} {
eval $script
}
如果您有真正对性能敏感的代码,请在不使用eval
的情况下编写代码。扩展语法 - {*}
- 可以在这里提供帮助,辅助程序也可以。或者用C或C ++或Fortran或......编写关键位(请参阅critcl和ffidl扩展包以获取执行此操作的详细方法的详细信息,如果DLL具有合适的{{1},则只需load
DLL。功能)。