gpt4 book ai didi

c# - 为什么本地数组的读/写速度比静态数组快?

转载 作者:可可西里 更新时间:2023-11-01 07:54:00 28 4
gpt4 key购买 nike

我正在编写一些基准测试来弄清楚为什么类似的纯算法(没有 C++ lib/.net 内置类)在 C++ 中的运行速度比在 C# 中快得多,即使考虑到预期的功能差异也是如此。在这样做的同时,我偶然发现了这两个让我感到困惑的测试,有没有人知道为什么一个比另一个慢得多?第二个唯一的区别(在我的机器上需要 51 毫秒,而在我的机器上需要 88 毫秒)是这两个数组是在方法中本地声明的,而不是在外部声明的。在这两种情况下,数组都是在我们开始计时之前创建的。

    const int Runs = 100;
const int Width = 5000;
const int Height = 5000;
const int Size = Width * Height;


static int[] Input = Enumerable.Range(0, Size).ToArray();
static int[] Output = new int[Size * 2];

static int SimpleTest()
{
// Removing those 2 lines and using the static arrays instead give substantially slower performance, nearly half the speed!
int[] Input = Enumerable.Range(0, Size).ToArray();
int[] Output = new int[Size * 2];

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

for (int run = 0; run < Runs; run++)
{
int InputIndex = 0;
for (int x = 0; x < Width; x++)
{
for (int y = 0; y < Height; y++)
{
int pixel = Input[InputIndex];
var OutputIndex = InputIndex * 2;
Output[OutputIndex] = pixel;
Output[OutputIndex + 1] = pixel;
InputIndex++;
}
}
}
sw.Stop();
return (int)(sw.ElapsedMilliseconds / Runs);
}

最佳答案

当变量是本地变量时,编译器知道 InputOutput 永远不会改变,这开启了许多优化。

  • InputOutput 变量的值可以保存在寄存器中。
  • Input.LengthOutput.Length 可以计算一次并缓存。
  • 编译器可以证明Input[InputIndex]Output[OutputIndex]永远不会导致数组索引越界,所以边界检查可以被优化掉.
  • 编译器可以观察到 InputOutput 的结果从未被使用,因此它可以将循环优化为空!

如果您使用静态版本,则编译器无法执行这些优化。编译器必须在每次访问时重新加载 InputOutput,并且必须在每次数组索引操作时执行边界检查,以防另一个线程修改 Input输出

例如,如果另一个线程执行 Input = new int[Size],那么所有 future 的计算都必须使用这个备用的 Input 进行。如果另一个线程执行 Output = new int[1],则代码必须引发 IndexOutOfRangeException

关于c# - 为什么本地数组的读/写速度比静态数组快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30205997/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com