在C#中将decimal[][]转换为double[][]

3
我想将我的2D十进制数组转换为双精度数组。我希望这样做既高效又整洁。这个看起来很好,也很整洁。那么如何扩展到2D数组呢?
我是否需要遍历第一维,并应用Linq /委托风格的命令,或者有其他方法可以使用更少的代码完成它?
PS:我不太关心超过3-4小数位数的精度损失。
更新:根据评论的要求,这是我提出的虽然要避免的内容:
double[][] inputs = new double[inputsArray.Length][];
for (int i = 0; i < inputsArray.Length; i++)
{
    inputs[i] = Array.ConvertAll(inputsArray[i], x => (double)x);
}

请分享你尝试过的代码。 - Aju Mon
2个回答

5

不幸的是,使用锯齿数组您将需要分别转换每个数组,但仍然可以在一行代码中完成:

doubleArray = Array.ConvertAll(decimalArray, da => Array.ConvertAll(da, d => (double)d));

或者使用Linq:
doubleArray = decimalArray.Select(da => da.Select(d => (double)d).ToArray()).ToArray(); 

要确定哪个更快,您需要试一下;Array.ConvertAll 可能通过组合委托和数组创建来进行一些优化。

基准测试

为了解决性能问题的争议,我对三种提出的解决方案进行了基准测试:

  1. Array.Convert
  2. Linq
  3. 循环

以下是代码和结果

int I = 10000;
int J = 1000;

Random rand = new Random();

decimal[][] decimalArray = new decimal[I][];

decimalArray = Enumerable.Range(1,I).Select(i => 
     Enumerable.Range(1, J).Select (j => (decimal)rand.NextDouble()).ToArray()
   ).ToArray();


Stopwatch s = new Stopwatch();

// Array.ConvertAll
s.Start();
var doubleArray = Array.ConvertAll(decimalArray, da => Array.ConvertAll(da, d => (double)d));
s.Stop();
s.Dump();

// Linq    
s.Restart();
doubleArray = decimalArray.Select(da => da.Select(d => (double)d).ToArray()).ToArray(); 
s.Stop();
s.Dump();

// Loops
s.Restart();
doubleArray = new double[I][];
for(int i = 0; i < I; i++)
{
    decimal[] dda = decimalArray[i];
    doubleArray[i] = new double[dda.Length];
    double[] da = doubleArray[i];
    for(int j = 0; j < dda.Length; j++)
    {
        da[j] = (double)dda[j];
    }
}
s.Stop();
s.Dump();


Method          ElapsedMilliseconds 
-------------   ----------------------
Array.Convert   310 
Linq            478 
Loops           287   (7.5% faster that Array.Convert)

你可以决定,一个7.5%的速度提升是否值得增加7倍的代码量。


如果你想要效率,不要为每个元素调用委托。 - usr
@usr - 你有什么替代方案建议吗? - D Stanley
1
Presumably ConvertAll 在其实现中使用循环结构? - rex
@ArmenSafieh-Garabedian:是的,但@usr的观点是ConvertAll在循环中调用委托(x) => (double)x,这比直接在循环内部转换为双精度浮点数效率低... - digEmAll
1
@ArmenSafieh-Garabedian 是的-你可以自行查看 - D Stanley
显示剩余2条评论

4
你可以将两个`Array.ConvertAll`连接起来,例如:
var dec2D = new decimal[100][];
var dbl2D = Array.ConvertAll(dec2D, x => Array.ConvertAll(x, y => (double)y));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接