为什么重新分配缓冲区比重置缓冲区更快?

时间:2018-08-14 14:33:17

标签: c# performance buffer

在重构一些旧代码时,我决定进行一些毫无意义的过早优化,并重新使用缓冲区,而不是每次都重新分配它。 令我惊讶的是,我发现它的运行速度非常慢。

复制:

    private static void Main(string[] args)
    {
        const int N = (int)1e4;
        const int size = 100 * 1024;

        var sw = Stopwatch.StartNew();
        var buffer = new byte[size];
        for (int n = 0; n < N; n++)
        {
            buffer = new byte[size];
        }
        var reallocMs = sw.ElapsedMilliseconds;

        sw = Stopwatch.StartNew();
        buffer = new byte[size];
        for (int n = 0; n < N; n++)
        {
            for (int i = 0; i < buffer.Length; i++)
            {
                buffer[i] = 0;
            }
        }
        var rewriteMs = sw.ElapsedMilliseconds;

        Console.WriteLine($"Reallocating: {reallocMs} ms");
        Console.WriteLine($"Rewriting: {rewriteMs} ms");

        Console.WriteLine($"Rewrite / reallocate = {(double)rewriteMs / (double)reallocMs}");
    }

当内置于Release中时,重写每个字节比重新分配新缓冲区慢大约8倍。在Debug中,它的速度降低了近50倍!

这怎么可能?我希望使用固定的缓冲区可以提高性能,但是事实并非如此。

我在这里想念什么?

PS:而且,Array.Clear()始终比for循环还要慢 ,尽管其性能与构建配置无关。

1 个答案:

答案 0 :(得分:2)

每次写入数组时,它都可能引发异常。因此,在循环实现中的每次写入时,都会对索引进行边界检查。首次初始化已知内存范围时,可以对其进行优化。