扩展阵列的最快方法

时间:2013-06-05 15:21:16

标签: c# arrays c#-4.0

我正在寻找扩展数组的最快方法。 无论是长度+ 1还是长度+ x,它都必须是最快的方式。

以下是一个例子:

var arr = new int [200];
for(int = 0; i < 200; i++)
   arr[i] = i;

现在我想从索引位置20开始为5个项目扩展arr。

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

6 个答案:

答案 0 :(得分:4)

创建一个所需大小的新数组,然后使用静态Array.Copy方法将原始数组复制到新数组中。

你无法扩展&#34;一个数组,你只能创建一个更大的数组并将原文复制到其中。

另外,请考虑使用List<int>LinkedList<>而不是数组,除非您需要对内存中的内容进行非常精细的控制。

答案 1 :(得分:2)

使用List要容易得多。但是如果必须使用数组,则必须创建大小为205的新数组并从两个源数组复制值,因为数组大小是常量。

答案 2 :(得分:2)

最好的办法是使用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有点痛苦,因为它需要字节偏移,这是代码中所有乘法乘以4的原因。您可能最好在上面的第二个版本中使用Array.Copy。这样可以防止你将所有东西乘以4(有时会遗忘)。

答案 3 :(得分:1)

如果您知道数组将该长度维持到该长度,

var ints  = new int[someFixedLength];

如果您对长度有一个想法,请使用通用列表。

var ints = new List<int>(someVagueLength);

这两种类型都实现IList但是,List类型处理内部数组的重新定义通常是“最快”的方式。


注意: .Count的初始List将为0,但内部数组的大小将调整为传递给构造函数的大小。


如果您需要在数组之间复制数据,最快的方法是Buffer.BlockCopy,所以从您的示例中

Buffer.BlockCopy(arr2, 0, arr, sizeof(int) * 20, sizeof(int) * 5);

5的所有int arr2复制到20的{​​{1}},21 ... 24内。

使用c#(当前)没有更快的方法。

答案 4 :(得分:1)

答案显示了时间基准:Best way to combine two or more byte arrays in C#。如果您将“插入的数组”视为数组1和3,将“要插入的数组”视为数组2,则“连接三个数组”示例将直接应用。

注意接受答案结尾处的要点:创建速度更快的方法会产生一个访问速度较慢的数组(这就是为什么我问你是否关心创建速度或访问速度)。

答案 5 :(得分:0)

使用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();