克隆锯齿状数组比多维数组慢

时间:2018-05-25 09:28:18

标签: c# .net multidimensional-array jagged-arrays

我试图克隆一个大小约为100x100的多维数组,而我发现的每一个资源似乎都表明使用锯齿状数组应该更有效(至少在查找中因为多维数组使用了一个函数 - 呼叫)。

但是我的问题是我对这些数组进行了大量的克隆,并且克隆锯齿状数组(在循环中分配新数组)似乎比执行multArray.Clone()要慢得多。

示例代码:

class Program
    {
        static void Main(string[] args)
        {
            int matSize = 100;
            int iterations = 100000;
            Random r = new Random();
            Stopwatch sw = new Stopwatch();
            double[][] jaggedMat = new double[matSize][];
            double[,] multiMat = new double[matSize, matSize];
            for(int i = 0; i < matSize; i++)
            {
                jaggedMat[i] = new double[matSize];
                for (int j = 0; j < matSize; j++)
                {
                    double v = r.NextDouble();
                    jaggedMat[i][j] = v;
                    multiMat[i, j] = v;
                }
            }
            Console.WriteLine($"Cloning jagged matrix old school.");
            sw.Start();
            for (int i=0; i<iterations; i++)
            {
                double[][] copy = new double[matSize][];
                for(int j = 0; j <matSize; j++)
                {
                    copy[j] = new double[matSize];
                    for (int k = 0; k < matSize; k++)
                    {
                        copy[j][k] = jaggedMat[j][k];
                    }
                }
            }
            sw.Stop();
            Console.WriteLine($"Cloning took {sw.ElapsedMilliseconds}ms");
            Console.WriteLine($"Cloning using LINQ");
            sw.Reset();
            sw.Start();
            for (int i = 0; i < iterations; i++)
            {
                var clone = jaggedMat.Select(element => element.ToArray()).ToArray();
            }
            sw.Stop();
            Console.WriteLine($"Cloning took {sw.ElapsedMilliseconds}ms");
            Console.WriteLine($"Cloning multidimensional array.");
            sw.Reset();
            sw.Start();
            for(int i = 0; i < iterations; i++)
            {
                var clone = multiMat.Clone() as double[,];
            }
            sw.Stop();
            Console.WriteLine($"Cloning took {sw.ElapsedMilliseconds}ms");
            Console.ReadKey();
        }
    }

这会在我的电脑上产生以下输出:

克隆参差不齐的矩阵老派。 克隆需要4913毫秒 使用LINQ进行克隆 克隆花了2283ms 克隆多维数组。 克隆需要712ms

正如您所看到的,在相同大小的矩阵上执行.Clone()的速度比实际分配新的锯齿状数组快约3倍。

任何人都知道是否有更快的方法来克隆锯齿状阵列?

2 个答案:

答案 0 :(得分:2)

这样做:

double[][] copy = new double[matSize][];
for (int j = 0; j < matSize; j++)
{
    copy[j] = jaggedMat[j].Clone() as double[];
}

它会使锯齿状阵列比多维阵列慢2倍(在我的机器上2450ms对比1360ms)。简而言之,创建100个对象(锯齿状阵列的线条)会产生成本。 GC会讨厌你:-)所有这些对象都必须分配,然后在GC运行时释放。这使得锯齿状阵列克隆速度变慢。我说有趣的是成本是如此之慢(似乎创建一个阵列与填充它的成本相同,因为多维克隆是纯粹的填充,而锯齿状阵列克隆是半复制和一半创建数组)

答案 1 :(得分:0)

我没有测量过表现。但是你可以用更少的代码来解决这个问题。我的解决方案序列化和反序列化整个数组以获得它的深层副本。

using System.Runtime.Serialization.Formatters.Binary;
BinaryFormatter formatter = new BinaryFormatter();
using(var ms = new MemoryStream())
{
   var array = new int[100, 100];
   array [0, 1] = 57; // simple test data to validate the output.
   formatter.Serialize(ms, array );
   ms.Position = 0; // rewind the stream to deserialize it.
   var copied = formatter.Deserialize(ms);
}