[英]Fastest way to extend array
我正在尋找擴展數組的最快方法。 無論僅對於長度+ 1還是長度+ x,它都必須是最快的方法。
這是一個例子:
var arr = new int [200];
for(int = 0; i < 200; i++)
arr[i] = i;
現在我想從索引位置20開始將arr擴展為5個項目。
var arr2 = new int [] { 999, 999, 999, 999, 999 }
如何通過使用最快的方式將arr2放在arr內?
結果應如下所示0,1,2,3,4 .... 20,999,999,999,999,999,21,22,23,24 .... 199
創建一個所需大小的新數組,然后使用靜態Array.Copy
方法將原始數組復制到新數組中。
您不能“擴展”數組,只能創建更大的數組並將原始數組復制到其中。
另外,考慮使用List<int>
或LinkedList<>
而不是數組,除非您需要對內存中的內容進行非常細粒度的控制。
使用List容易得多。 但是,如果必須使用數組,則必須創建大小為205的新數組,並從兩個源數組復制值,因為數組大小是恆定的。
最好的選擇是使用List<int>
類的東西,而不是數組。 但是,如果必須使用數組:
int[] arr1 = new int[200];
// initialize array
int[] arr2 = new int[]{999, 999, 999, 999, 999};
int targetPos = 20;
// resizes the array, copying the items
Array.Resize(ref arr1, arr1.Length + arr2.Length);
// move the tail of the array down
Buffer.BlockCopy(arr1, 4*targetPos, arr1, 4*(targetPos+arr2.Length), 4*(arr1.Length - targetPos));
// copy arr2 to the proper position
Buffer.BlockCopy(arr2, 0, 4*arr1.targetPos, 4*arr2.Length);
這樣創建新數組並復制項目可能會更快。
int[] newArray = new int[arr1.Length + arr2.Length];
// copy first part of original array
Buffer.BlockCopy(arr1, 0, newArray, 0, 4*targetPos);
// copy second array
Buffer.BlockCopy(arr2, 0, newArray, 4*targetPos, 4*arr2.Length);
// copy remainder of original array
Buffer.blockCopy(arr1, 4*targetPos, newArray, 4*(targetPos + arr2.Length), 4*(arr1.Length - targetPos));
// and replace the original array
arr1 = newArray;
哪個版本更快,將取決於targetPos
位置。 當targetPos
較小時,第二個版本會更快。 當targetPos
較小時,第一個版本必須復制大量數據兩次。 第二個版本永遠不會復制過多的副本。
BlockCopy
有點BlockCopy
,因為它需要字節偏移量,這就是代碼中所有乘四的原因。 在上面第二個版本中使用Array.Copy可能會更好。 這樣可以避免將所有內容乘以4(有時會忘記)。
如果您知道將數組調整為該長度的長度,
var ints = new int[someFixedLength];
如果對長度有很大的想法,請使用通用列表。
var ints = new List<int>(someVagueLength);
兩種類型都實現IList
但是List
類型處理內部數組的重新命名通常是“最快”的方法。
注意: List
的初始.Count
將為0
但是內部數組的大小將根據傳遞給構造函數的大小確定。
如果需要在數組之間復制數據,最快的方法是Buffer.BlockCopy
,因此從您的示例
Buffer.BlockCopy(arr2, 0, arr, sizeof(int) * 20, sizeof(int) * 5);
將所有5
int
從s arr2
到indecies 20
, 21
... 24
的arr
。
目前沒有使用c#的更快方法。
這里給出了顯示時序基准的答案: 在C#中組合兩個或更多字節數組的最佳方法 。 如果將“要插入的數組”視為數組1和3,將“要插入的數組”視為數組2,則“連接三個數組”示例將直接適用。
請注意已接受答案的結尾處的要點:創建速度更快的方法產生的數組訪問速度較慢(這就是為什么我問您是否關心創建速度或訪問速度的原因)。
使用System.Linq您可以執行以下操作,通過向其中添加一個新對象來擴展數組...
int[] intA = new int[] { 1, 2, 3 };
int intB = 4;
intA = intA.Union(new int[] { intB }).ToArray();
...或者您可以通過向其添加另一個項目數組來擴展數組...
int[] intA = new int[] { 1, 2, 3 };
int[] intB = new int[] { 4, 5, 6 };
intA = intA.Union(intB).ToArray();
...或者如果您不在乎重復...
int[] intA = new int[] { 1, 2, 3 };
int[] intB = new int[] { 4, 5, 6 };
intA = intA.Concat(intB).ToArray();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.