基准测试方法调用C#

我正在寻找一种在C#中对方法调用进行基准测试的方法。

我已经编写了一个用于大学分配的数据结构,并且想出了一种优化一点的方法,但是在某种情况下会在所有情况下增加一些开销,同时将O(n)调用转换为O(1)在一些。

现在我想针对测试数据运行两个版本,看看是否值得实现优化。 我知道在Ruby中,您可以将代码封装在Benchmark块中,并让它输出在控制台中执行块所需的时间 – 是否有类似C#的可用内容?

您可以使用内置的秒表类 “提供一组方法和属性,您可以使用它们来准确测量经过的时间。” 如果您正在寻找手动方式来做到这一点。 虽然不确定自动化。

从Yuriy的回答中被盗(和修改):

private static void Benchmark(Action act, int iterations) { GC.Collect(); act.Invoke(); // run once outside of loop to avoid initialization costs Stopwatch sw = Stopwatch.StartNew(); for (int i = 0; i < iterations; i++) { act.Invoke(); } sw.Stop(); Console.WriteLine((sw.ElapsedMilliseconds / iterations).ToString()); } 

通常,特定方法必须初始化某些内容,并且您并不总是希望将这些初始化成本包含在整体基准测试中。 此外,您希望将总执行时间除以迭代次数,以便您的估计值或多或少地与迭代次数无关。

以下是我通过试验和错误发现的一些事情。

  1. 丢弃第一批(数千)次迭代。 他们很可能会受到JITter的影响。
  2. 在单独的Thread对象上运行基准测试可以提供更好,更稳定的结果。 我不知道为什么。
  3. 在执行基准测试之前,我已经看到有些人出于某种原因使用Thread.Sleep 。 这只会让事情变得更糟。 我不知道为什么。 可能是由于JITter。
  4. 永远不要在启用调试的情 代码最有可能运行速度慢几个数量级。
  5. 在启用所有优化的情况下编译应用程序。 某些代码可能会受到优化的严重影响,而其他代码则不会,因此在没有优化的情况下进行编译会影响基准测试的可靠性。
  6. 在启用优化的情况下进行编译时,有时需要以某种方式评估基准测试的输出(例如,打印值等)。 否则,编译器可能“弄清楚”某些计算是无用的,并且根本不会执行它们。
  7. 在执行某些基准测试时,调用代理会产生明显的开销。 最好在委托中放置多个迭代,这样开销对基准测试的结果几乎没有影响。
  8. Profilers可以有自己的开销。 他们擅长告诉你代码的哪些部分是瓶颈,但他们并不擅长对两个不同的东西进行可靠的基准测试。
  9. 通常,花哨的基准测试解决方案可能会有明显的开销。 例如,如果要使用一个接口对许多对象进行基准测试,则可能很容易将每个对象包装在一个类中。 但是,请记住,类构造函数也有必须考虑的开销。 最好保持一切尽可能简单直接。

我从Jon Skeet的基准测试方法中偷走了以下大部分内容:

 private static void Benchmark(Action act, int interval) { GC.Collect(); Stopwatch sw = Stopwatch.StartNew(); for (int i = 0; i < interval; i++) { act.Invoke(); } sw.Stop(); Console.WriteLine(sw.ElapsedMilliseconds); } 

听起来你想要一个分析器 。 我自己强烈推荐EQATEC探查器 ,它是我尝试过的最好的免费探测器 。 与简单的秒表相比,这种方法的优点在于它还提供了某些方法/块的性能细分。

Profilers提供了最好的基准测试,因为他们诊断了所有代码,但是它们减慢了很多。 分析器用于查找瓶颈。

为了优化算法,当您知道瓶颈所在的位置时,请使用名称字典 – >秒表,以便在运行时跟踪性能关键部分。