我需要找到一个瓶颈,并需要尽可能准确地测量时间。

下面的代码片段是衡量性能的最佳方法吗?

DateTime startTime = DateTime.Now;

// Some execution process

DateTime endTime = DateTime.Now;
TimeSpan totalTimeTaken = endTime.Subtract(startTime);

当前回答

这不够专业:

Stopwatch sw = Stopwatch.StartNew();
PerformWork();
sw.Stop();

Console.WriteLine("Time taken: {0}ms", sw.Elapsed.TotalMilliseconds);

更可靠的说法是:

PerformWork();

int repeat = 1000;

Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < repeat; i++)
{
   PerformWork();
}

sw.Stop();

Console.WriteLine("Time taken: {0}ms", sw.Elapsed.TotalMilliseconds / repeat);

在我的实际代码中,我将添加GC。收集调用以将托管堆更改为已知状态,并添加Sleep调用,以便在ETW配置文件中轻松分离不同的代码间隔。

其他回答

我在程序中使用的方式是使用StopWatch类,如下所示。

Stopwatch sw = new Stopwatch();
sw.Start();


// Critical lines of code

long elapsedMs = sw.Elapsed.TotalMilliseconds;

秒表也一样,它好多了。

关于性能度量,你还应该检查你的“// Some Execution Process”是否是一个非常短的过程。

还要记住,“// Some Execution Process”的第一次运行可能比后续运行慢得多。

我通常通过在循环中运行1000次或100万次来测试一个方法,我得到的数据比运行一次要准确得多。

@Sean钱伯斯

供您参考,.NET Timer类不是用于诊断的,它以预设的时间间隔生成事件,如下(来自MSDN):

System.Timers.Timer aTimer;
public static void Main()
{
    // Create a timer with a ten second interval.
    aTimer = new System.Timers.Timer(10000);

    // Hook up the Elapsed event for the timer.
    aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);

    // Set the Interval to 2 seconds (2000 milliseconds).
    aTimer.Interval = 2000;
    aTimer.Enabled = true;

    Console.WriteLine("Press the Enter key to exit the program.");
    Console.ReadLine();
}

// Specify what you want to happen when the Elapsed event is 
// raised.
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
    Console.WriteLine("The Elapsed event was raised at {0}", e.SignalTime);
}

所以这并不能帮助你知道某件事花了多长时间,只是告诉你某段时间已经过去了。

计时器也作为一个控件在System.Windows.Forms…你可以在VS05/VS08的设计器工具箱中找到它

这是正确的方法:

using System;
using System.Diagnostics;

class Program
{
    public static void Main()
    {
        Stopwatch stopWatch = Stopwatch.StartNew();

            // some other code

        stopWatch.Stop();

        // this not correct to get full timer resolution
        Console.WriteLine("{0} ms", stopWatch.ElapsedMilliseconds);

        // Correct way to get accurate high precision timing
        Console.WriteLine("{0} ms", stopWatch.Elapsed.TotalMilliseconds);
    }
}

要了解更多信息,请使用秒表而不是DataTime来获得准确的性能计数器。

秒表的功能会更好(精度更高)。我还建议下载一款流行的分析器(DotTrace和ANTS是我用得最多的…免费试用的DotTrace功能齐全,不像其他一些唠叨)。