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()。