将List <double>转换为double [n,1]

时间:2020-04-09 13:43:13

标签: c# arrays

我需要将长度为n的大型列表转换为double [n,1]数组。进行转换的最快方法是什么?

为进一步了解背景,此方法将传递给需要二维数组的Excel对象的Range.Value。

2 个答案:

答案 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
相关问题