TCL性能测试-为什么波动这么大?

TCL性能测试-为什么波动这么大?,tcl,Tcl,为了测量TCL脚本的运行时间,我在以下文件中修改了TCL8.4.20源代码: 基本效用 记录时间: c,在Tcl_Main()函数中,在调用Tcl_FSEvalFile()之前,记录时间 tclBasic.c,在Tcl_EvalEx()中,开始时记录时间;有多个出口,记录每个出口的时间 c,在退出Tcl_Main()之前,转储所有录制 像往常一样构建TCL源代码,可执行tclsh8.4现在有了我的内置函数来记录脚本运行时,并在最后转储时间 我使用一行脚本:放置hello 令我惊讶的是,运行时间变

为了测量TCL脚本的运行时间,我在以下文件中修改了TCL8.4.20源代码:

  • 基本效用 记录时间:
  • c,在Tcl_Main()函数中,在调用Tcl_FSEvalFile()之前,记录时间

  • tclBasic.c,在Tcl_EvalEx()中,开始时记录时间;有多个出口,记录每个出口的时间

  • c,在退出Tcl_Main()之前,转储所有录制

  • 像往常一样构建TCL源代码,可执行tclsh8.4现在有了我的内置函数来记录脚本运行时,并在最后转储时间

  • 我使用一行脚本:
    放置hello

    令我惊讶的是,运行时间变化很大。这是一个连续的时间:

    run1 - 232.00ms
    run2 - 7886.00ms
    run3 - 6973.00ms
    run4 - 5749.00ms
    run5 - 224.00ms
    run6 - 6820.00ms
    run7 - 6074.00ms
    run8 - 221.00ms
    
    也许字节码版本有更好的一致性?因此,我向Tcl_EvalObjEx和TclExecuteByteCode()添加了更多的探测。以下是新脚本:

    proc p {} {
      puts hello
    }
    
    p
    
    但这也不一致:

    run1 - 226.00ms
    run2 - 7877.00ms
    run3 - 6964.00ms
    run4 - 5740.00ms
    run5 - 218.00ms
    run6 - 6809.00ms
    run7 - 6064.00ms
    run8 - 216.00ms
    
    你知道可能有什么问题吗

    [更新] 可能
    put
    是一个错误的选择,因为它是受许多系统问题影响的I/O函数,所以我将脚本更改为一些随机命令:

    set a 100
    set b 200
    append a 300
    array set arr1 {one 1 two 2}
    
    这肯定更好:

    run1 - 9.00ms
    run2 - 9.00ms
    run3 - 19.00ms
    run4 - 9.00ms
    run5 - 9.00ms
    run6 - 9.00ms
    run7 - 9.00ms
    run8 - 9.00ms
    run9 - 9.00ms
    run10 - 9.00ms
    

    但是,19毫秒的运行是如何产生的呢?

    使用挂钟计时的问题是,它对系统上发生的任何事情都非常敏感。操作系统可以简单地决定在任何时候暂停进程,理由是CPU还有其他“更重要”的工作要做。它不知道您正在尝试进行性能度量

    解决这一问题的通常方法是运行多次计时脚本,并将测量的计时减至最小,记住计时的成本根本不是零,并且可能会对输出产生影响

    标准Tcl中的
    time
    命令就是针对这种情况的。下面是一个使用示例:

    puts [time {
        set a 100
        set b 200
        append a 300
        array set arr1 {one 1 two 2}
    } 100]
    
    这将运行100次之前的代码片段,并打印平均执行时间。(在我的性能密集型测试中,我会使用一大堆稳定代码,这样我甚至可以从微基准中获得合理的信息,但他们真正做的只是猜测迭代的一个好值,并打印一组样本中的最小值。此外,微基准最终可能会有数百个迭代计数数千或数百万。)


    请注意,您正在使用的Tcl版本已经过时。8.5是当前的LTS版本(也就是说,它主要只接受安全修复(如果有的话;我们没有很多Vuln)和支持不断发展的OS API的更新),8.6是用于新工作的。(8.7和9.0正在开发中,但仍处于alpha之前。)

    puts [time {
        set a 100
        set b 200
        append a 300
        array set arr1 {one 1 two 2}
    } 100]