Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Array.Clear()与Buffer.BlockCopy()的比较 背景_C# - Fatal编程技术网

C# Array.Clear()与Buffer.BlockCopy()的比较 背景

C# Array.Clear()与Buffer.BlockCopy()的比较 背景,c#,C#,我必须经常清除固定长度字节数组(例如:byte[4096]) 我的问题是寻找一个适用于一般用法的答案,但对于那些想知道这个问题从何而来的人来说:我目前正在优化我的byte[]对象池。当它回到游泳池时,我需要把它擦干净 我的问题 使用Array.Clear()方法清除数组或使用 Buffer.BlockCopy()方法使用空数组覆盖数组, 哪种方法性能更好 示例代码 使用Buffer.BlockCopy清除字节数组 Buffer.BlockCopy(blankArray, 0, array,

我必须经常清除固定长度字节数组(例如:
byte[4096]

我的问题是寻找一个适用于一般用法的答案,但对于那些想知道这个问题从何而来的人来说:我目前正在优化我的
byte[]
对象池。当它回到游泳池时,我需要把它擦干净


我的问题 使用
Array.Clear()
方法清除数组或使用
Buffer.BlockCopy()
方法使用空数组覆盖数组, 哪种方法性能更好


示例代码 使用
Buffer.BlockCopy
清除字节数组

Buffer.BlockCopy(blankArray, 0, array, 0, 4096);
Array.Clear(array, 0, 4096);
-与-

使用
Array.Clear
清除字节数组

Buffer.BlockCopy(blankArray, 0, array, 0, 4096);
Array.Clear(array, 0, 4096);

我的研究 ArrayClear()结果

 Total elapsed time was 3.22 seconds.
 Total garbage collection (generation 0) was 0 collections.
 Total garbage collection (generation 1) was 0 collections.
 Total garbage collection (generation 2) was 0 collections.
 Average processing time per iteration took 0.32 microseconds.
 Total elapsed time was 0.90 seconds.
 Total garbage collection (generation 0) was 0 collections.
 Total garbage collection (generation 1) was 0 collections.
 Total garbage collection (generation 2) was 0 collections.
 Average processing time per iteration took 0.09 microseconds.
似乎
ArrayClear
更快。我不确定这是否意味着它的性能也更好


您的研究得出了正确的结论:
Array.Clear()
在这种特定情况下优于
Buffer.BlockCopy()

基准点网络 要运行这样的基准测试,请使用。您的基准可以简化并使用BenchmarkDotNet运行,如下所示:

using System;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;

namespace Experiments
{
    [MemoryDiagnoser]
    public class Test
    {
        const int SIZE = 4096;
        static byte[] _blank = new byte[SIZE];
        static byte[] _array = new byte[SIZE];

        [Benchmark]
        public void ArrayClear()
        {
            Array.Clear(_array, 0, SIZE);
        }

        [Benchmark]
        public void BlockCopy()
        {
            Buffer.BlockCopy(_blank, 0, _array, 0, SIZE);
        }
    }

    public class Program
    {
        static void Main(string[] args)
        {
            BenchmarkRunner.Run<Test>();
        }
    }
}

您的研究得出了正确的结论:
Array.Clear()
在这种特定情况下优于
Buffer.BlockCopy()

基准点网络 要运行这样的基准测试,请使用。您的基准可以简化并使用BenchmarkDotNet运行,如下所示:

using System;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;

namespace Experiments
{
    [MemoryDiagnoser]
    public class Test
    {
        const int SIZE = 4096;
        static byte[] _blank = new byte[SIZE];
        static byte[] _array = new byte[SIZE];

        [Benchmark]
        public void ArrayClear()
        {
            Array.Clear(_array, 0, SIZE);
        }

        [Benchmark]
        public void BlockCopy()
        {
            Buffer.BlockCopy(_blank, 0, _array, 0, SIZE);
        }
    }

    public class Program
    {
        static void Main(string[] args)
        {
            BenchmarkRunner.Run<Test>();
        }
    }
}

您是否使用benchmarkdotnet或类似工具测量了时间?对于
Buffer.BlockCopy
您需要两个数组。这是一个额外的内存分配,等等,没有增益。如果
Array.Clear
没有以您需要的速度运行(这不太可能),您可以使用不安全的代码并使用64位写入来擦除阵列。它不会比这快很多。你也可以使用
RtlZeroMemory
,尽管如果你有一个预先分配的字节数组(假设大小总是相同的,并且只读取过),
Buffer.BlockCopy
将是你最简单的选择-无需导入,而且速度非常快。最后,如果您真的降低到了这种性能差异级别,您可能应该按照Marc的建议对其进行计时,基准中有一个简单的错误,它意外地颠倒了方法的名称。实际上是Array.Clear()更快。当然,直觉上很明显。Buffer.BlockCopy()仍然有一些不稳定的地方,当您将数组作为参数传递时,它会更快一些。这种情况的原因并不十分明显,但这并不重要,因为您喜欢Array.Clear()。您是否使用benchmarkdotnet或类似工具测量了时间?对于
Buffer.BlockCopy
,您需要两个数组。这是一个额外的内存分配,等等,没有增益。如果
Array.Clear
没有以您需要的速度运行(这并不太可能),则可以使用不安全的代码并使用64位写入擦除数组。它不会比这快很多。你也可以使用
RtlZeroMemory
,尽管如果你有一个预先分配的字节数组(假设大小总是相同的,并且只读取过),
Buffer.BlockCopy
将是你最简单的选择-无需导入,而且速度非常快。最后,正如Marc所建议的,如果你真的达到了这样的性能差异水平,你可能应该计时。基准测试中有一个简单的输入错误,它意外地颠倒了方法的名称。实际上是Array.Clear()更快。当然,直觉上很明显。Buffer.BlockCopy()仍然有一些不稳定的地方,当您将数组作为参数传递时,它会更快一些。这种情况的原因并不完全清楚,但这并不重要,因为您还是喜欢Array.Clear()。