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

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

DateTime startTime = DateTime.Now;

// Some execution process

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

当前回答

这是正确的方法:

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来获得准确的性能计数器。

其他回答

这篇文章说,首先你需要比较三个替代品,秒表,日期时间。Now AND DateTime.UtcNow。

它还显示在某些情况下(当性能计数器不存在时)Stopwatch正在使用DateTime。UtcNow +一些额外的处理。因此,在这种情况下,DateTime很明显。UtcNow是最好的选择(因为其他使用它+一些处理)

然而,事实证明,计数器几乎总是存在的-参见关于高分辨率性能计数器及其与. net秒表相关的存在的解释?

这是一个性能图表。请注意UtcNow的性能成本与其他选项相比有多低:

X轴是样本数据的大小,Y轴是样本的相对时间。

秒表更好的一点是它能提供更高分辨率的时间测量。另一个原因是它更加面向对象。然而,围绕UtcNow创建一个OO包装器并不难。

秒表也一样,它好多了。

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

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

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

不,不是。使用秒表(在系统诊断中)

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

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

秒表自动检查是否存在高精度计时器。

值得一提的是DateTime。Now通常比DateTime慢一些。UtcNow是因为需要在时区、夏令时等方面做一些工作。

DateTime。UtcNow的分辨率通常为15毫秒。请看John Chapman关于DateTime的博客文章。现在我们来做一个精确的总结。

有趣的琐事:秒表回落到DateTime。UtcNow如果你的硬件不支持高频计数器。你可以通过查看静态字段Stopwatch. ishighresolution来检查Stopwatch是否使用硬件来实现高精度。

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

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

因为我不太关心精度,所以我最终比较了它们。我正在捕获网络上的大量数据包,我想在我收到每个数据包时放置时间。下面是测试500万次迭代的代码

    int iterations = 5000000;

    // Test using datetime.now
    {
        var date = DateTime.UtcNow.AddHours(DateTime.UtcNow.Second);

        var now = DateTime.UtcNow;

        for (int i = 0; i < iterations; i++)
        {
            if (date == DateTime.Now)
                Console.WriteLine("it is!");
        }
        Console.WriteLine($"Done executing {iterations} iterations using datetime.now. It took {(DateTime.UtcNow - now).TotalSeconds} seconds");
    }

    // Test using datetime.utcnow
    {
        var date = DateTime.UtcNow.AddHours(DateTime.UtcNow.Second);

        var now = DateTime.UtcNow;

        for (int i = 0; i < iterations; i++)
        {
            if (date == DateTime.UtcNow)
                Console.WriteLine("it is!");
        }
        Console.WriteLine($"Done executing {iterations} iterations using datetime.utcnow. It took {(DateTime.UtcNow - now).TotalSeconds} seconds");
    }

    // Test using stopwatch
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();

        var now = DateTime.UtcNow;

        for (int i = 0; i < iterations; i++)
        {
            if (sw.ElapsedTicks == DateTime.Now.Ticks)
                Console.WriteLine("it is!");
        }
        Console.WriteLine($"Done executing {iterations} iterations using stopwatch. It took {(DateTime.UtcNow - now).TotalSeconds} seconds");
    }

输出结果为:

Done executing 5000000 iterations using datetime.now. It took 0.8685502 seconds 
Done executing 5000000 iterations using datetime.utcnow. It took 0.1074324 seconds 
Done executing 5000000 iterations using stopwatch. It took 0.9625021 seconds

总之,DateTime。如果您不太关心精度,UtcNow是最快的。这也支持了这个问题的答案https://stackoverflow.com/a/6986472/637142。