2011-05-10 47 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