如何在C#中初始化整数数组

mas*_*2k1 5 .net c#

可能重复:
c#Leaner初始化int数组的方法

基本上我想知道是否有比下面显示的更有效的代码

    private static int[] GetDefaultSeriesArray(int size, int value)
    {
        int[] result = new int[size];
        for (int i = 0; i < size; i++)
        {
            result[i] = value;
        }
        return result;
    }
Run Code Online (Sandbox Code Playgroud)

大小可以从10到150000不等.对于小阵列不是问题,但应该有更好的方法来做到这一点.我正在使用VS2010(.NET 4.0)

Ale*_*kov 8

C#/ CLR没有内置的方法来使用非默认值初始化数组.

如果您测量每个项目的操作,您的代码就会高效.

如果并行初始化大型数组的块,则可以获得更快的初始化.由于mutlithread操作的非平凡成本,这种方法需要仔细调整.

通过分析您的需求并可能完全删除整个初始化,可以获得更好的结果.即如果数组通常包含常量值,您可以实现某种COW(写入时复制)方法,其中您的对象最初没有后备数组并且simpy返回常量值,写入它将创建的元素(可能是部分)后备数组修改段.

可以使用更慢但更紧凑的代码(可能更容易阅读)Enumerable.Repeat.请注意,这ToArray将导致为大型阵列分配大量内存(也可能最终在LOH上进行分配) - 使用Enumerable.Range进行高内存消耗?.

 var result = Enumerable.Repeat(value, size).ToArray();
Run Code Online (Sandbox Code Playgroud)

  • 这将是相当低效**,而不是*更高效*. (5认同)

Ser*_*rvy 4

提高速度的一种方法是利用Array.Copy. 它能够在较低级别上工作,在该级别上批量分配较大的内存部分。

通过批处理分配,您最终可以将数组从一个部分复制到自身。

最重要的是,批次本身可以非常有效地并行化。

这是我的初始代码。在我的机器(只有两个核心)上,样本数组大小为 1000 万个项目,我获得了 15% 左右的加速。您需要调整批量大小(尝试保持页面大小的倍数以保持高效),以将其调整为您拥有的项目的大小。对于较小的数组,它最终将与您的代码几乎相同,因为它不会超过填充第一批,但在这些情况下它也不会(明显)更糟。

private const int batchSize = 1048576;
private static int[] GetDefaultSeriesArray2(int size, int value)
{

    int[] result = new int[size];

    //fill the first batch normally
    int end = Math.Min(batchSize, size);
    for (int i = 0; i < end; i++)
    {
        result[i] = value;
    }

    int numBatches = size / batchSize;

    Parallel.For(1, numBatches, batch =>
    {
        Array.Copy(result, 0, result, batch * batchSize, batchSize);
    });

    //handle partial leftover batch
    for (int i = numBatches * batchSize; i < size; i++)
    {
        result[i] = value;
    }

    return result;
}
Run Code Online (Sandbox Code Playgroud)