1

我正在寻找扩展数组的最快方法。无论仅对于 length + 1 或 length + 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

4

6 回答 6

4

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

您不能“扩展”数组,只能创建一个更大的数组并将原始数组复制到其中。

此外,请考虑使用List<int>orLinkedList<>代替数组,除非您需要对内存中的内容进行非常细粒度的控制。

于 2013-06-05T15:25:05.757 回答
2

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

于 2013-06-05T15:25:22.087 回答
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(有时会忘记)。

于 2013-06-05T15:42:24.570 回答
1

如果您知道数组将其维数到该长度多长时间,

var ints  = new int[someFixedLength];

如果您对长度有一个模糊的概念,请使用通用列表。

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

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


注意:的初始.CountList0但是,内部数组的大小将被确定为您传递给构造函数的大小。


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

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

将所有5 ints 从复制arr2到 indecies 20, 21... 24of arr

使用 c#(目前)没有更快的方法来做到这一点。

于 2013-06-05T15:29:14.813 回答
1

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

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

于 2013-06-05T15:43:22.020 回答
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();
于 2019-04-25T19:24:50.593 回答