Performance 加速Tcl评估

Performance 加速Tcl评估,performance,tcl,eval,Performance,Tcl,Eval,我目前正在为符号矩阵操作编写一个基于Tcl的工具,但代码速度越来越慢。我正在寻找加速我的Tcl代码(Tcl 8.6版)的方法 我有一个怀疑。我的代码构建列表时,命令名作为第一个元素,命令参数作为以下元素(这来自模拟面向对象的方法)。我使用eval调用这些命令(这通常在递归处理中完成)。我在上读到,eval可能很慢 我有三个问题: 从包含命令名和参数的列表中调用命令的最快方法是什么 将命令名myCmd和参数列表myPar分开,并使用[$myCmd{*}$myPar]调用该命令,这会加快代码的速度

我目前正在为符号矩阵操作编写一个基于Tcl的工具,但代码速度越来越慢。我正在寻找加速我的Tcl代码(Tcl 8.6版)的方法

我有一个怀疑。我的代码构建列表时,命令名作为第一个元素,命令参数作为以下元素(这来自模拟面向对象的方法)。我使用
eval
调用这些命令(这通常在递归处理中完成)。我在上读到,
eval
可能很慢

我有三个问题:

  • 从包含命令名和参数的列表中调用命令的最快方法是什么

  • 将命令名
    myCmd
    和参数列表
    myPar
    分开,并使用
    [$myCmd{*}$myPar]
    调用该命令,这会加快代码的速度吗(建议在

  • 在8.6中,使用
    if 1
    而不是
    eval
    的技巧是否仍然有希望


  • 非常感谢你的帮助

    最重要的是,不要假设:
    time
    。在对事物计时时要注意,重复运行一个事物可能会改变它运行所需的时间(缓存预热时)。仔细考虑一下你想要什么样的速度

    eval
    命令通常速度较慢,但并非所有情况下都如此。如果您给它一个您已经构建的列表(例如,使用
    list
    linsert
    lappend
    或…),那么它相当快,因为它可以避免重新划分输入;它知道,但只有在这种情况下,它才能直接跳到分派到命令实现。另一种快速的情况是,当您给它一个以前给
    eval
    的值时;字节码已经生成并缓存。这些注释也适用于
    uplevel

    $myCmd{*}$myParameters
    也相当快;这被字节编码为“在Tcl操作数堆栈上组装单词并执行正确的命令分派”,这与任意用户命令非常接近(很少有直接字节码实现)

    我希望使用
    if 1时,某些情况下速度非常快,而另一些情况下速度非常慢;它强制进行完整的编译,因此,如果可以很好地缓存内容,那么缓存速度就会很快,如果不能很好地缓存内容,那么缓存速度就会很慢。如果你只是在调用一个命令,充其量也不会有太大的区别。它获胜的情况是,被调用的对象本身是字节编码的命令,并且可以正确缓存对象

    如果您正在处理一个普通命令(例如,一个过程,或者一个接触操作系统的Tcl命令),我会选择选项2:
    $myCmd{*}$myParameters
    或其变体。这大概是你能达到的最快速度。但我不会:

    set myParameters [linsert $myOriginalValues 0 "literal1" [cmdOutput2] $value3]
    $myCmd {*}$myParameters
    
    那太可笑了。这更清晰、更干净、更快:

    $myCmd "literal1" [cmdOutput2] $value3 {*}$myOriginalValues
    

    扩展点语法(
    {*}
    )的一部分是,您不需要进行复杂的参数编组,这很好,因为复杂度很难始终正确无误。

    最重要的是,不要假设:
    时间
    确实如此。在对事物计时时要注意,重复运行一个事物可能会改变它运行所需的时间(缓存预热时)。仔细考虑一下你想要什么样的速度

    eval
    命令通常速度较慢,但并非所有情况下都如此。如果您给它一个您已经构建的列表(例如,使用
    list
    linsert
    lappend
    或…),那么它相当快,因为它可以避免重新划分输入;它知道,但只有在这种情况下,它才能直接跳到分派到命令实现。另一种快速的情况是,当您给它一个以前给
    eval
    的值时;字节码已经生成并缓存。这些注释也适用于
    uplevel

    $myCmd{*}$myParameters
    也相当快;这被字节编码为“在Tcl操作数堆栈上组装单词并执行正确的命令分派”,这与任意用户命令非常接近(很少有直接字节码实现)

    我希望使用
    if 1时,某些情况下速度非常快,而另一些情况下速度非常慢;它强制进行完整的编译,因此,如果可以很好地缓存内容,那么缓存速度就会很快,如果不能很好地缓存内容,那么缓存速度就会很慢。如果你只是在调用一个命令,充其量也不会有太大的区别。它获胜的情况是,被调用的对象本身是字节编码的命令,并且可以正确缓存对象

    如果您正在处理一个普通命令(例如,一个过程,或者一个接触操作系统的Tcl命令),我会选择选项2:
    $myCmd{*}$myParameters
    或其变体。这大概是你能达到的最快速度。但我不会:

    set myParameters [linsert $myOriginalValues 0 "literal1" [cmdOutput2] $value3]
    $myCmd {*}$myParameters
    
    那太可笑了。这更清晰、更干净、更快:

    $myCmd "literal1" [cmdOutput2] $value3 {*}$myOriginalValues
    
    扩展点语法(
    {*}
    )的一部分是,您不需要进行复杂的参数编组,这很好,因为复杂度很难始终正确无误。

    关于

    避免在内存中复制数据。改变

    set mylist [linsert $mylist 0 some new content]
    

    这将取消对变量值的引用,然后将变量设置为 空字符串。这会减少变量的引用计数

    另请参见

    关于

    避免在内存中复制数据。改变

    set mylist [linsert $mylist 0 some new content]
    

    这将取消对变量值的引用,然后将变量设置为 空字符串。这会减少变量的引用计数


    另请参见

    如果您有类似于
    set cmd[list mycmd arg1 arg2…]
    的内容,那么您可以使用
    {*}$cmd
    调用它。我怀疑您的代码可能由于传递了大量数据而变慢。请特别查看“取消共享对象”部分。@glennjackman:T