关于c#:使用单个值填充数组的最快方法

Fastest way to fill an array with a single value

本问题已经有最佳答案,请猛点这里访问。

我想用我拥有的单个值填充一个二维数组,但是,我想以最快的方式填充它,因为二维数组的总长度将为200K+,随着时间的推移,这些数组将超过200个。不过,我已经研究了buffer.blockcopy和array.copy,它们都将数组作为源/目标,其中我拥有的唯一数组是目标,而源是单个值。

用源是单个值而不是数组填充数组的最快方法是什么?


我找到的最快的方法是使用array.copy,每次在循环中副本大小都翻倍。无论是用一个值填充数组还是用一个值数组填充数组,速度基本相同。

在我对20000000个数组项的测试中,这个函数的速度是for循环的两倍。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
using System;

namespace Extensions
{
    public static class ArrayExtensions
    {
        public static void Fill<T>(this T[] destinationArray, params T[] value)
        {
            if (destinationArray == null)
            {
                throw new ArgumentNullException("destinationArray");
            }

            if (value.Length >= destinationArray.Length)
            {
                throw new ArgumentException("Length of value array must be less than length of destination");
            }

            // set the initial array value
            Array.Copy(value, destinationArray, value.Length);

            int arrayToFillHalfLength = destinationArray.Length / 2;
            int copyLength;

            for(copyLength = value.Length; copyLength < arrayToFillHalfLength; copyLength <<= 1)
            {
                Array.Copy(destinationArray, 0, destinationArray, copyLength, copyLength);
            }

            Array.Copy(destinationArray, 0, destinationArray, copyLength, destinationArray.Length - copyLength);
        }
    }
}

我在http://coding.grax.com/2011/11/initialize-array-to-value-in-c-very.html和http://coding.grax.com/2014/04/better-array-fill-function.html上写了这个博客。


Array.Copy可能比for循环更好地优化,所以使用它。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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循环之间的性能比较,针对不同的类型和数组大小)


有关一些相关信息,请参见C中memset的等效值是多少?.

正如在那个问题中提到的(非常接近于这个问题的重复),for循环通常是最好的,除非您想进入非托管代码。

所以这应该很快:

1
2
3
4
5
int[] arr = new int[MAX_ELEMENTS];
for (int i = 0; i < arr.Length; ++i)
{
    array[i] = MY_VALUE;
}

和所有与性能相关的事情一样,让一些东西工作,然后测量瓶颈是什么。强调"测量"。试图猜测瓶颈是什么通常是一个坏主意(: