首页 > 解决方案 > 从两个不同长度的数组中获取值的不同时间

问题描述

我很惊讶从第一个数组按索引获取值需要比第二个数组更多的时间。它不依赖于数组长度,在我的测试中,任何组合都是如此。我想这取决于一些低级优化。有人可以解释一下吗?代码示例如下:

            var a1 = new int[10];
            var a2 = new int[1000000];

            #region init
            var random = new Random(12345);

            for (int i = 0; i < a1.Length; i++)
                a1[i] = random.Next(1000000000);

            for (int i = 0; i < a2.Length; i++)
                a2[i] = random.Next(1000000000);

            #endregion

            Console.WriteLine("a1 Length = " + a1.Length);
            var watcher = Stopwatch.StartNew();

            var t1 = a1[a1.Length / 2];

            watcher.Stop();
            Console.WriteLine("a1 timestamp = " + watcher.ElapsedTicks); // average value 130-150 ticks


            Console.WriteLine("a2 Length = " + a2.Length);
            watcher = Stopwatch.StartNew();

            var t2 = a2[a2.Length / 2];
            watcher.Stop();
            Console.WriteLine("a2 timestamp = " + watcher.ElapsedTicks); //average value 10 - 15 ticks


            Console.ReadLine();

我的结果是: - 通过索引从长度为 10 的数组中获取值是 ~130-150 滴答 - 通过索引从长度为 1000000 的数组中获取值是 ~10-15 滴答

标签: c#

解决方案


我建议您更改测量性能的方式,但让我们假设您的测量是正确的。这里可能有几个原因,其中之一是分支预测。简而言之,现代处理器正在使用分支预测进行计算。

正如维基百科上所说:

分支预测器的目的是改善指令流水线中的流程。分支预测器在许多现代流水线微处理器架构(如 x86)中实现高效性能方面发挥着关键作用。

所以数字电路试图识别一种模式并遵循它。如果您每次都猜对,执行将永远不会停止并且执行速度很快,如果您经常猜错,您会花费大量时间回滚并重新启动。出于同样的原因,处理排序数组比处理未排序数组更快。


推荐阅读