Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 克隆交错数组比多维数组慢_C#_.net_Multidimensional Array_Jagged Arrays - Fatal编程技术网

C# 克隆交错数组比多维数组慢

C# 克隆交错数组比多维数组慢,c#,.net,multidimensional-array,jagged-arrays,C#,.net,Multidimensional Array,Jagged Arrays,我试图克隆一个大小约为100x100的多维数组,我找到的每一个资源似乎都表明使用交错数组应该更有效(至少在查找中,因为多维数组使用函数调用) 但我的问题是,我对这些数组进行了大量克隆,这似乎比只克隆multArray.Clone()要慢得多 示例代码: class Program { static void Main(string[] args) { int matSize = 100; int iterat

我试图克隆一个大小约为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();
        }
    }
类程序
{
静态void Main(字符串[]参数)
{
int matSize=100;
int迭代次数=100000次;
随机r=新随机();
秒表sw=新秒表();
double[]jaggedMat=新的double[matSize][];
double[,]multiMat=新的double[matSize,matSize];
对于(int i=0;i对于(int i=0;i我没有测量性能。但是您可以用更少的代码来解决这个问题。我的解决方案序列化和反序列化整个数组,以获得它的深度副本

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);
}

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

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);
}
这样做:

double[][] copy = new double[matSize][];
for (int j = 0; j < matSize; j++)
{
    copy[j] = jaggedMat[j].Clone() as double[];
}
double[]copy=new double[matSize][];
对于(int j=0;j
它只会使锯齿状数组比多维数组慢2倍(在我的机器上是2450ms对1360ms)。简单地说,创建100个对象(锯齿状数组的行)是有成本的。GC会有点讨厌你:-)如果GC运行,所有这些对象都必须被分配,然后被释放。这使得锯齿状数组的克隆速度变慢。我要说的是,成本如此之低是很有趣的(鉴于多维克隆是纯填充,而锯齿阵列克隆是半复制半创建阵列,因此创建阵列的成本似乎与填充阵列的成本相同)

请执行以下操作:

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

它只会使锯齿状数组比多维数组慢2倍(在我的机器上是2450ms对1360ms)。简单地说,创建100个对象(锯齿状数组的行)是有成本的。GC会有点讨厌你:-)如果GC运行,所有这些对象都必须被分配,然后被释放。这使得锯齿状数组的克隆速度变慢。我要说的是,成本如此之低是很有趣的(鉴于多维克隆是纯填充,而锯齿状数组克隆是半复制半创建数组,因此创建数组的成本似乎与填充数组的成本相同)

我希望您是在发布模式下运行测试,并且没有调试器(CTRL+F5或直接在命令行中)…我经常在测试开始时添加一个
Process.GetCurrentProcess().PriorityClass=ProcessPriorityClass.High;
,以提高程序运行期间的优先级。我会说克隆锯齿状数组应该更慢。请注意,可以半克隆锯齿状数组(克隆每一行):
copy[j]=锯齿状[j].克隆为双精度[]
实际上我没有,从命令行运行测试产生了类似的结果:克隆锯齿矩阵老派。克隆需要3801ms使用LINQ克隆需要1600ms克隆多维数组。克隆需要484ms在Core i7上使用Benchmark.NET,我在10000次迭代中得到了以下结果:老派:140.38ms,LINQ:151.74 ms,Multi:47.5 ms。您基本上发现了Array.Clone()在CLR内部经过了微优化,它可以使用原始memcpy而无需绑定检查。您永远无法打败它。这也适用于锯齿阵列,但它的惊人速度有助于您发现Clone()的问题,它不是一个深度副本。您通常希望避免索引副本[j]和jaggedMat[j],它们是循环不变的。但是抖动优化器可以自己解决这个问题。我希望您在发布模式下运行测试,并且没有调试器(CTRL+F5或直接在命令行中)…我经常添加
进程。GetCurrentProcess().PriorityClass=ProcessPriorityClass.High;
在测试开始时,为了提高程序运行期间的优先级,我会说克隆锯齿状数组应该更慢。请注意,可以半克隆锯齿状数组(克隆每一行):
copy[j]=锯齿状[j]。克隆为双[]
实际上我没有,从命令行运行测试产生了类似的结果:克隆锯齿矩阵老派。克隆需要3801ms使用LINQ克隆需要1600ms克隆多维数组。克隆需要484ms在Core i7上使用Benchmark.NET,我在10000次迭代中得到了以下结果:老派:140.38ms,LINQ:151.74 ms,Multi:47.5 ms。您基本上发现了Array.Clone()在CLR内部经过了微优化,它可以使用原始memcpy而无需绑定检查。您永远无法打败它。这也适用于锯齿阵列,但它的惊人速度有助于您发现Clone()的问题,它不是一个深度副本。您通常希望避免索引副本[j]和jaggedMat[j],它们是循环不变的。但是抖动优化器可以自己解决这个问题。我会尝试一下,但要注意的是,您将多维数组称为“jaggedArray”当它不是。是的,那是真的。我的解决方案适用于任何可序列化的对象。如果有人感兴趣,你的方法产生了与l类似的结果