我需要将长度为n的大型列表转换为double [n,1]数组。进行转换的最快方法是什么?
为进一步了解背景,此方法将传递给需要二维数组的Excel对象的Range.Value。
答案 0 :(得分:4)
我写这篇文章的前提是您真的想要最有效的方法。极高的性能几乎总是需要权衡取舍,通常是代码可读性。
我仍然可以在注释中充分优化其中的一部分,但是我不想在初次通过时使用动态方法。
const int TEST_SIZE = 100 * 1000;
//Test data setup
var list = new List<double>();
for (int i = 0; i < TEST_SIZE; i++)
list.Add(i);
//Grab the list's underlying array, which is not public
//This can be made MUCH faster with dynamic methods if you want me to optimize
var underlying = (double[])typeof(List<double>)
.GetField("_items", BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(list);
//We need the actual length of the list because there can be extra space in the array
//Do NOT use "underlying.Length"
int underlyingLength = list.Count;
//Benchmark it
var sw = Stopwatch.StartNew();
var twodarray = new double[underlyingLength, 1];
Buffer.BlockCopy(underlying, 0, twodarray, 0, underlyingLength * sizeof(double));
var elapsed = sw.Elapsed;
Console.WriteLine($"Elapsed: {elapsed}");
输出:
已过去:00:00:00.0001998
使用的硬件:
AMD锐龙7 3800X @ 3.9 Ghz 32 GB DDR4 3200 RAM
答案 1 :(得分:1)
我想这就是你想要的。
即使在速度较慢的内核上,此操作也不会超过几毫秒。那为什么要打扰呢?您将进行多少次转换?如果数百万次,则比尝试寻找更好的方法。但是如果您在最终用户按下按钮时执行此操作...
批评答案,但是请提供有关效率的指标。
// Populate a List with 100.000 doubles
Random r = new Random();
List<double> dList = new List<double>();
int i = 0;
while (i++ < 100000) dList.Add(r.NextDouble());
// Convert to double[100000,1]
Stopwatch chrono = Stopwatch.StartNew();
// Conversion:
double[,] ddArray = new double[dList.Count, 1];
int dIndex = 0;
dList.ForEach((x) => ddArray[dIndex++, 0] = x);
Console.WriteLine("Completed in: {0}ms", chrono.Elapsed);
输出:(10次重复)-最大:2.6毫秒
Completed in: 00:00:00.0020677ms
Completed in: 00:00:00.0026287ms
Completed in: 00:00:00.0013854ms
Completed in: 00:00:00.0010382ms
Completed in: 00:00:00.0019168ms
Completed in: 00:00:00.0011480ms
Completed in: 00:00:00.0011172ms
Completed in: 00:00:00.0013586ms
Completed in: 00:00:00.0017165ms
Completed in: 00:00:00.0010508ms
编辑1。
double[,] ddArray = new double[dList.Count, 1];
foreach (double x in dList) ddArray[dIndex++, 0] = x;
似乎更快一些,但需要更多测试:
Completed in: 00:00:00.0020318ms
Completed in: 00:00:00.0019077ms
Completed in: 00:00:00.0023162ms
Completed in: 00:00:00.0015881ms
Completed in: 00:00:00.0013692ms
Completed in: 00:00:00.0022482ms
Completed in: 00:00:00.0015960ms
Completed in: 00:00:00.0012306ms
Completed in: 00:00:00.0015039ms
Completed in: 00:00:00.0016553ms