簡體   English   中英

克隆鋸齒狀數組比多維數組慢

[英]Cloning jagged array is slower than multidimensional array

我正在嘗試克隆大小約為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();
        }
    }

這將在我的計算機上產生以下輸出:

克隆鋸齒狀的老派。 克隆耗時4913ms使用LINQ進行克隆克隆耗時2283ms克隆多維數組。 克隆耗時712ms

如您所見,在相同大小的矩陣上執行.Clone()大約比實際分配新的鋸齒形數組快約3倍。

任何人都知道是否有更快的克隆鋸齒陣列的方法?

做這個:

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運行時將其釋放。 這使得鋸齒狀陣列的克隆速度變慢。 我會說有趣的是,成本如此之慢(鑒於多維克隆是純填充,而鋸齒狀的陣列克隆是一半復制,一半是創建數組,因此創建數組與填充它的成本似乎相同)。數組)

我沒有衡量性能。 但是您可以用更少的代碼來解決這個簡單得多的問題。 我的解決方案對整個數組進行序列化和反序列化以獲得其深層副本。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM