Tcl eval命令会阻止字节编码吗?

时间:2014-12-23 10:40:31

标签: tcl eval bytecode

我知道在某些动态的解释语言中,使用eval会减慢速度,因为它会停止字节编码。
在Tcl 8.5中是这样吗?
感谢

1 个答案:

答案 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。功能)。