2011-05-10 45 views
13

我想填充一个具有单个值的二维数组,但是,我希望以最快的方式完成二维数组的长度为总计200k +,随着时间的推移,这些阵列中将会有200多个。我已经查看了Buffer.BlockCopy和Array.Copy,但是,它们都将数组作为源/目标,其中唯一的数组就是目标,源是单个值。使用单个值填充数组的最快方法

什么是最快的方式来填充一个数组与源是一个单一的值,而不是一个数组?

+0

有几个不同的方式,这家伙已经列出了几个比较常见的 - 他甚至还跟基准它: http://www.dotnetperls.com/initialize-array在内存中保存200K项目,即使它们是原始内存,也会占用大量内存 - 你在做什么,你需要所有200K的项目可用实时访问(每个项目)? – debracey 2011-05-10 00:26:35

+0

可能不是一个重复的问题,他没有说他想用数组来初始化数组,可能也意味着用一个瓦尔来填充数组的大部分 – user613326 2015-11-05 14:27:49

回答

1

有关相关信息,请参阅What is the equivalent of memset in C#?

正如在这个问题(非常接近这个愚蠢)中提到的,for循环通常是最好的,除非你想进入unmanaged code

所以这应该是相当快:

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

正如所有的东西与性能相关,得到的东西的工作,然后进行测量的瓶颈是什么。强调“措施”。试图猜测的瓶颈是什么通常是一个坏主意(:

1

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循环,不同类型和阵列大小之间的比较)

8

我发现最快的方法使用Array.Copy与副本大小加倍每次通过循环无论你填写的速度基本相同具有单个值或数组值的数组。

在我测试的20,000,000个数组项中,该函数的速度是for循环的两倍。

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.htmlhttp://coding.grax.com/2014/04/better-array-fill-function.html

+2

我需要填充一个[,]的数组,因此我复制了你的' Fill'延伸,改变了签名 '公共静态无效填写(此T [,] destinationArray,T [,]值)' 并把它称为像这样: 'myLargeArray.Fill(新[,] {{double.NaN},{double.NaN}});' 它工作得很好。谢谢! – Kaboo 2017-05-10 00:12:33