首页 > 解决方案 > 如何比较代码的执行时间?

问题描述

我想有一个系统,我可以编写一些代码来测试它的速度,所以我做了这个:

class Program {

    public static IEnumerable<long> Tests {
        get {

            Stopwatch stopwatch = new Stopwatch();
            Random random = new Random();

            {
                stopwatch.Start();

                _ = $"There are {random.NextDouble() * 100:N1} things. That's like {random.Next()}!";

                stopwatch.Stop();
                yield return stopwatch.ElapsedTicks;
            }

            stopwatch.Reset();

            {
                stopwatch.Start();

                _ = "There are " + (random.NextDouble() * 100).ToString("N5") + "things. That's like " + random.Next() + "!";

                stopwatch.Stop();
                yield return stopwatch.ElapsedTicks;
            }

        }
    }

    static void Main(string[] args) {

        int iterations = 1000000;
        var times = new List<long>();

        foreach(long time in Tests) {
            times.Add(time);
        }

        for(int iteration = 1; iteration < iterations; iteration++) {

            int testID = 0;
            foreach(long time in Tests) {
                times[testID++] += time;
            }

        }

        Console.WriteLine($"After {iterations:N0} iteration{(iterations == 1 ? "" : "s")}:");
        for(int testID = 0; testID < times.Count; testID++) {
            Console.WriteLine($"\tTest {testID + 1} took an average of {times[testID] / iterations:N0} nanoseconds.");
        }

    }

}

对于 1 次迭代(每次测试通过一次),我发现字符串插值大约需要 30,000ns,而字符串连接需要大约 2,000ns。哪个更快一目了然!...正确的?

以防万一,我尝试切换两个测试以找到...串联实际上需要约 35,000 纳秒,而插值实际上需要约 3,000ns。

然后我开始将迭代次数设置为更大的数字,并发现每次测试所需的时间会随着时间的推移而减少,平均下降到不到 10ns。

我发现另一个问题说原因是缓存,最好忽略第一个结果。通过运行测试而不保存结果 100 次然后运行 ​​1,000,000 次迭代,我得到了最一致的结果。插值测试始终在 9ns 完成,串联测试始终在 7ns 完成。然而,即便如此,无论哪个是第一个测试,都会慢 1ns。

是否甚至可以运行代码时间测试来确定需要多长时间?

标签: c#

解决方案


推荐阅读