C# 重复一段代码来度量它的健壮性有多强';什么时候执行?

C# 重复一段代码来度量它的健壮性有多强';什么时候执行?,c#,performance,C#,Performance,假设我想测量MyFunction()执行的时间 我们还可以说MyFunction()执行速度很快(几毫秒),秒表无法以足够高的精度测量函数时间 然后,我将把MyFunction()放在一个执行1000000次的循环中,并对其进行测量。我将对循环的执行计时,然后将结果除以循环执行的次数 问题是: 这个测量有多精确?我基本上想知道要多久 第一次执行MyFunction()需要的时间,而不是平均时间 需要 执行同一函数的时间是否线性缩放?是吗 取决于MyFunction()的属性(因此需要某种缓存

假设我想测量
MyFunction()
执行的时间

我们还可以说
MyFunction()
执行速度很快(几毫秒),秒表无法以足够高的精度测量函数时间

然后,我将把
MyFunction()
放在一个执行1000000次的循环中,并对其进行测量。我将对循环的执行计时,然后将结果除以循环执行的次数

问题是:

  • 这个测量有多精确?我基本上想知道要多久 第一次执行
    MyFunction()
    需要的时间,而不是平均时间 需要

  • 执行同一函数的时间是否线性缩放?是吗 取决于
    MyFunction()
    的属性(因此需要某种缓存 使用的是什么?那些是什么财产


假设您在3秒内运行了
MyFunction()
1000000次

你现在知道了:

  • 您至少有时可以在小于或等于3μs的时间内,在类似的数据和类似的缓存和抖动情况下运行
    MyFunction()

  • 只要测试是真正等效的,它可能比需要3.5秒的等效方法运行得更快。(但3.01太接近了,除非它一直重复,否则无法确定)

  • 只要测试是真正等效的,它可能比需要2.5秒的等效方法运行得慢。(但2.99太接近了,除非它一直重复,否则无法确定)

  • 你不知道:

  • 在第一次调用时,jitting、静态构造函数以及静态值或与所使用的特定值相关的值的记忆对时间的影响程度

  • 仍然可以从指令缓存访问的方法对时间的影响程度(或者实际上,是否可以)

  • 所使用的数据仍然可以从数据缓存中访问(或者是否可以访问)对时间的影响程度

  • 第一次运行后时间的一致性;每次运行是稳定的3μs,还是更常见的1μs,偶尔出现较大延迟

  • 究竟有多少时间花在循环而不是运行上

  • 这五件你不知道的事情(或者如果你在循环之前跑了一次,至少减少了第一件的影响,那就有四件)意味着你绝对不知道太多


    但是,与其他可能的方法相比,你知道的三件事可能非常有用,或者如果你明显高于或低于某个阈值(如果你需要超过2μs,你就完蛋了;如果你需要超过500μs,你就没事了;如果你需要持续地超过4μs,你就不知道你是否做到了)。

    假设你运行了
    MyFunction()
    1000000次,在3秒内完成

    你现在知道了:

  • 您至少有时可以在小于或等于3μs的时间内,在类似的数据和类似的缓存和抖动情况下运行
    MyFunction()

  • 只要测试是真正等效的,它可能比需要3.5秒的等效方法运行得更快。(但3.01太接近了,除非它一直重复,否则无法确定)

  • 只要测试是真正等效的,它可能比需要2.5秒的等效方法运行得慢。(但2.99太接近了,除非它一直重复,否则无法确定)

  • 你不知道:

  • 在第一次调用时,jitting、静态构造函数以及静态值或与所使用的特定值相关的值的记忆对时间的影响程度

  • 仍然可以从指令缓存访问的方法对时间的影响程度(或者实际上,是否可以)

  • 所使用的数据仍然可以从数据缓存中访问(或者是否可以访问)对时间的影响程度

  • 第一次运行后时间的一致性;每次运行是稳定的3μs,还是更常见的1μs,偶尔出现较大延迟

  • 究竟有多少时间花在循环而不是运行上

  • 这五件你不知道的事情(或者如果你在循环之前跑了一次,至少减少了第一件的影响,那就有四件)意味着你绝对不知道太多


    但是,与其他可能的方法相比,你知道的三件事可能非常有用,或者如果你明显高于或低于某个阈值(如果你需要超过2μs,你就完蛋了;如果你需要超过500毫秒,你就没事了;如果你需要持续地超过4μs,你就不知道你是否做到了)。

    秒表的精度大于“几毫秒”…就像余数一样,在对方法进行基准测试之前,至少执行一次,以便CLR对其进行JIT。函数的第一次执行可能涉及正在编译的代码(在后续调用中不会发生这种情况)。这可能会使第一次调用的时间不具有代表性。请注意,如果我们说的是“2加法和1乘法”,那么我们所处的范围比毫秒小得多。在该范围内,
    Stopwatch
    不起作用:-)以及jitting,由于加载缓存、数据库缓冲等,特定方法的第一次执行可能会较慢@Polyfun,然后一般来说,方法可以使用
    static
    成员/构造函数首次访问对象,并加载整个程序集。。。在方法的第一次运行中会发生很多事情…秒表的精度大于“几毫秒”。。。正如余数一样,在对方法进行基准测试之前,至少执行一次,以便CLR对其进行JIT。函数的第一次执行可能涉及正在编译的代码(在后续调用中不会发生这种情况)。这可能会使第一次通话的时间变得不准确