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

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

DateTime startTime = DateTime.Now;

// Some execution process

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

当前回答

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

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


// Critical lines of code

long elapsedMs = sw.Elapsed.TotalMilliseconds;

其他回答

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

@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的设计器工具箱中找到它

这些都是衡量时间的好方法,但这只是发现瓶颈的一种非常间接的方法。

在线程中找到瓶颈的最直接方法是让它运行,当它正在做任何让您等待的事情时,使用暂停或中断键停止它。这样做几次。如果你的瓶颈占用了X%的时间,那么X%就是你在每次快照中捕捉到它的概率。

这里有一个更完整的解释,它是如何以及为什么工作的

将基准测试代码放入实用程序类/方法中是很有用的。StopWatch类不需要在错误时被丢弃或停止。最简单的为动作计时的代码是

public partial class With
{
    public static long Benchmark(Action action)
    {
        var stopwatch = Stopwatch.StartNew();
        action();
        stopwatch.Stop();
        return stopwatch.ElapsedMilliseconds;
    }
}

示例调用代码

public void Execute(Action action)
{
    var time = With.Benchmark(action);
    log.DebugFormat(“Did action in {0} ms.”, time);
}

下面是扩展方法的版本

public static class Extensions
{
    public static long Benchmark(this Action action)
    {
        return With.Benchmark(action);
    }
}

以及示例调用代码

public void Execute(Action action)
{
    var time = action.Benchmark()
    log.DebugFormat(“Did action in {0} ms.”, time);
}

Visual Studio Team System有一些功能可以帮助解决这个问题。从本质上讲,您可以编写单元测试,并将它们混合在不同的场景中,作为压力或负载测试的一部分对您的软件运行。这可能有助于识别对应用程序性能影响最大的代码区域。

微软的模式和实践小组在Visual Studio团队系统性能测试指南中提供了一些指导。