【发布时间】:2020-04-28 15:28:02
【问题描述】:
我知道如果我想复制一个相同类型的数组,我至少有 3 个选项,我可以使用双 for 循环,使用 Array.copy 或 Buffer.BulkCopy。这两种复制方法要快得多。例如,请参见此处:https://stackoverflow.com/a/33030421。
这两种复制方法都允许您仅复制二维数组的一部分,但 Array.copy 需要源和目标的等级相等,而 bulk.copy 则不需要。
我从 com 接口获取数据,然后将 doubles 或 int 作为对象传入。可以说我想在副本中加入演员表。我可以这样做:
Stopwatch watch = new Stopwatch();
const int width = 2;
const int depth = 10 * 1000000;
Random r = new Random(100);
object[,] objdata = new object[width, depth];
for (int i = 0; i < width; i++)
{
for (int j = 0; j < depth; j++)
{
objdata[i, j] = r.Next();
}
}
int[,] arr2dint = new int[width, depth];
watch.Reset();
watch.Start();
Array.Copy(objdata, 0, arr2dint, 0, objdata.GetLength(0) * objdata.GetLength(1));
watch.Stop();
Console.WriteLine("ArrayCopy to 2 dimensional array including cast took {0}", watch.ElapsedMilliseconds);
watch.Reset();
var bufferloopcast = new int[width, depth];
watch.Start();
for (int i = 0; i < width; i++)
{
for (int j = 0; j < depth; j++)
{
bufferloopcast[i, j] = (int)objdata[i, j];
}
}
watch.Stop();
Console.WriteLine("Loop-copy to 2 dimensional array including cast took {0} ms", watch.ElapsedMilliseconds);
现在复制方法比较慢。它还具有源和目标等级必须相等的限制,因此我不能使用它来仅复制数组的一部分(例如仅第一行)。
我无法使 Buffer.BulkCopy 工作,错误必须是原始类型。我试过这个,在wain:
int[,] buff2dint = new int[width, depth];
watch.Reset();
watch.Start();
int sizeo = Marshal.SizeOf(objdata[0, 0]);
Buffer.BlockCopy(objdata, 0, buff2dint, 0, objdata.GetLength(0) * objdata.GetLength(1)* sizeo);
watch.Stop();
Console.WriteLine("BufferCopy to 2 dimensional array including cast took {0}", watch.ElapsedMilliseconds);
那么,为什么 array.copy 变得这么慢?如果您需要包含演员表,那么复制 2d 数组或其部分的最佳方法是什么?
【问题讨论】:
-
作为一个小注解,你知道你可以为
intlitterals 使用分隔符吗? IMO 似乎更具可读性:const int depth = 10_000_000;