如何在C#中可靠地测量代码效率/复杂性/性能/昂贵?

时间:2014-08-08 03:08:48

标签: c# windows performance time-complexity

我的问题包括两部分:

  1. 除了使用Stopwatch等定时器之外,C#还有什么方法可以衡量计算工作量吗?以下是我一直在做的事情,但粒度不是很好,返回的结果每次都有所不同。我想知道是否有更精确的措施,如CPU操作计数,以便返回的结果可以保持一致。

            Stopwatch stopWatch = new Stopwatch();
            stopWatch.Start();
    
            //do work
    
            stopWatch.Stop();
    
            TimeSpan ts = stopWatch.Elapsed;
    
            Console.WriteLine(ts);
    
  2. 如果无法使用1中的替代方法,如何使性能测试结果变得更少变量?有哪些因素会导致结果发生变化?关闭所有其他应用程序运行帮助? (我确实尝试了但似乎没有显着效果。)如何在VM,沙箱等上运行测试?

  3. (在输入正在进行的文本之后,我意识到我也尝试过Visual Studio附带的性能分析功能。由于它使用的采样方法,测试结果看起来更粗糙。所以我也想排除那个选项)

2 个答案:

答案 0 :(得分:1)

您需要获得一个分析工具。但是,如果您在循环中多次运行测试,则可以更可靠地使用StopWatch,但只有在垃圾收集生成保持不变的情况下才会获取测试结果。

像这样:

var timespans = new List<TimeSpan>();
while (true)
{
    var count = GC.CollectionCount(0);
    var sw = Stopwatch.StartNew();
    /* run test here */
    sw.Stop();
    if (count == GC.CollectionCount(0))
    {
        timespans.Add(sw.Elapsed);
    }
    if (timespans.Count == 100)
    {
        break;
    }
}

那将给你100次测试,其中垃圾收集没有发生。然后,平均值非常适合工作。

如果您发现测试从未在不调用垃圾收集的情况下运行,那么请尝试计算触发的最小数量的GC,并仅在出现该数字时收集时间跨度。

答案 1 :(得分:1)

您可以查询系统性能计数器。 msdn doc for the System.Diagnostics.PerformanceCounter class有一些例子。使用此类,您可以查询“\ Process(your_process_name)\%Processor Time”。它是秒表的另一种选择,但我认为只使用秒表并平均多次运行是一个非常好的方法。

如果你需要的是更高分辨率的秒表,因为你试图测量一小段cpu时间,那么你可能会对High-Performance Counter感兴趣。