我想用一个单一的值填充一个二维数组,但是希望以最快的方式完成,因为这个二维数组的长度将总共达到超过20万,而且随着时间的推移,会有超过200个这样的数组。我研究了Buffer.BlockCopy和Array.Copy,但是它们都将数组作为源/目标,而我只有目标数组,源是一个单一的值。
如何用单一的值填充数组是最快的方法?
我想用一个单一的值填充一个二维数组,但是希望以最快的方式完成,因为这个二维数组的长度将总共达到超过20万,而且随着时间的推移,会有超过200个这样的数组。我研究了Buffer.BlockCopy和Array.Copy,但是它们都将数组作为源/目标,而我只有目标数组,源是一个单一的值。
如何用单一的值填充数组是最快的方法?
我找到的最快方法是使用Array.Copy,每次循环时复制大小加倍。无论您用单个值还是数组值填充数组,速度基本相同。
在我的测试中,对于 20,000,000 个数组项,该函数比 for 循环快两倍。
using System;
namespace Extensions
{
public static class ArrayExtensions
{
public static void Fill<T>(this T[] destinationArray, params T[] values)
{
if (destinationArray == null)
throw new ArgumentNullException(nameof(destinationArray));
Array.Copy(values, destinationArray, Math.Min(values.Length, destinationArray.Length));
if (values.Length >= destinationArray.Length)
return;
int arrayToFillHalfLength = destinationArray.Length / 2;
int copyLength;
for (copyLength = values.Length; copyLength < arrayToFillHalfLength; copyLength <<= 1)
{
Array.Copy(destinationArray, 0, destinationArray, copyLength, copyLength);
}
Array.Copy(destinationArray, 0, destinationArray, copyLength, destinationArray.Length - copyLength);
}
}
}
Fill
扩展方法,并将签名更改为public static void Fill<T>(this T[,] destinationArray, T[,] value)
然后像这样调用它:myLargeArray.Fill(new [,] { { double.NaN }, { double.NaN }});
它完美地工作了。谢谢! - Kabua有关相关信息,请参见C#中memset的等效物是什么?。
如上述问题所提到的(非常接近重复此问题),使用for循环通常是最好的选择,除非您想涉及非托管代码。
因此,这应该非常快:
int[] arr = new int[MAX_ELEMENTS];
for (int i = 0; i < arr.Length; ++i)
{
array[i] = MY_VALUE;
}
对于与性能相关的所有事情,先让某些东西工作,然后测量瓶颈所在。强调“测量”。试图猜测瓶颈通常是一个坏主意(:
Array.Copy
比 for 循环更容易优化,因此请使用它。
void FillArray<T>(T[] arr, T fillValue)
{
int i = 0;
if (arr.Length > 16) {
{
do {
array[i++] = fillValue;
} while (i < arr.Length)
while (i + 16 < arr.Length) {
Array.Copy(arr, 0, arr, i, 16);
i = i + 16;
}
}
while (i < arr.Length)
{
array[i++] = fillValue;
}
}