用单个值填充数组的最快方法
本文关键字:方法 数组 单个值 填充 | 更新日期: 2023-09-27 17:55:35
我想用我拥有的单个值填充 2D 数组,但是,我想以最快的方式做到这一点,让 2D 数组的长度总计为 200k+,随着时间的推移,这些数组将超过 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);
}
}
}
我在 https://grax32.com/2011/11/initialize-array-to-value-in-c-very.html 和 https://grax32.com/2014/04/better-array-fill-function.html 写了关于这个的博客
有关一些相关信息,请参阅 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;
}
}
(我很想看到这个和天真的 for 循环之间的性能比较,对于不同的类型和数组大小)