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

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


再生产:


    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 循环慢,尽管它的性能与构建配置无关。


白衣非少年
浏览 178回答 1
1回答

holdtom

每次写入数组时,它都可能引发异常。因此,在循环实现中的每次写入时,都会对索引进行边界检查。当第一次初始化已知范围的内存时,可以优化掉。
打开App,查看更多内容
随时随地看视频慕课网APP