Edit: je m'excuse auprès de tout le monde. J'ai utilisé le terme "tableau en escalier" quand en fait je voulais dire "un tableau multi-dimensionnel" (comme on peut le voir dans mon exemple ci-dessous). Je m'excuse pour l'utilisation du nom incorrect. J'ai effectivement trouvé les tableaux irréguliers pour être plus rapide que multi-dimensionnelle ceux! J'ai ajouté mes mesures pour les tableaux irréguliers.
J'ai essayé d'utiliser un jagged un tableau multi-dimensionnel aujourd'hui, quand j'ai remarqué que c'est la performance n'est pas que je l'aurais attendu. À l'aide d'un simple tableau multidimensionnel et manuellement le calcul des indices a été beaucoup plus rapide (presque deux fois) à l'aide d'un tableau 2D. J'ai écrit un test à l'aide de 1024*1024
tableaux initialisés à des valeurs aléatoires), pour 1000 itérations, et j'ai obtenu les résultats suivants sur ma machine:
sum(double[], int): 2738 ms (100%)
sum(double[,]): 5019 ms (183%)
sum(double[][]): 2540 ms ( 93%)
C'est mon code de test:
public static double sum(double[] d, int l1) {
// assuming the array is rectangular
double sum = 0;
int l2 = d.Length / l1;
for (int i = 0; i < l1; ++i)
for (int j = 0; j < l2; ++j)
sum += d[i * l2 + j];
return sum;
}
public static double sum(double[,] d) {
double sum = 0;
int l1 = d.GetLength(0);
int l2 = d.GetLength(1);
for (int i = 0; i < l1; ++i)
for (int j = 0; j < l2; ++j)
sum += d[i, j];
return sum;
}
public static double sum(double[][] d) {
double sum = 0;
for (int i = 0; i < d.Length; ++i)
for (int j = 0; j < d[i].Length; ++j)
sum += d[i][j];
return sum;
}
public static void Main() {
Random random = new Random();
const int l1 = 1024, l2 = 1024;
double[ ] d1 = new double[l1 * l2];
double[,] d2 = new double[l1 , l2];
double[][] d3 = new double[l1][];
for (int i = 0; i < l1; ++i) {
d3[i] = new double[l2];
for (int j = 0; j < l2; ++j)
d3[i][j] = d2[i, j] = d1[i * l2 + j] = random.NextDouble();
}
//
const int iterations = 1000;
TestTime(sum, d1, l1, iterations);
TestTime(sum, d2, iterations);
TestTime(sum, d3, iterations);
}
Complément d'enquête a montré que l'IL pour la deuxième méthode est de 23% plus grande que celle de la première méthode. (La taille du Code 68 vs 52.) Cela est principalement dû à des appels d' System.Array::GetLength(int)
. Le compilateur émet aussi des appels à l' Array::Get
pour le déchiquetés un tableau multi-dimensionnel, alors qu'il appelle simplement ldelem
, pour la simple tableau.
Alors je me demande, pourquoi est accessible par le biais de matrices multi-dimensionnelles plus lent que la normale tableaux? J'aurais cru le compilateur (ou JIT) serait de faire quelque chose de similaire à ce que j'ai fait dans ma première méthode, mais ce n'était pas vraiment le cas.
Pourriez-vous s'il vous plait m'aider à comprendre pourquoi cela se passe de cette manière?
Mise à jour: Suite à Henk Holterman la suggestion ici est la mise en œuvre de l' TestTime
:
public static void TestTime<T, TR>(Func<T, TR> action, T obj,
int iterations)
{
Stopwatch stopwatch = Stopwatch.StartNew();
for (int i = 0; i < iterations; ++i)
action(obj);
Console.WriteLine(action.Method.Name + " took " + stopwatch.Elapsed);
}
public static void TestTime<T1, T2, TR>(Func<T1, T2, TR> action, T1 obj1,
T2 obj2, int iterations)
{
Stopwatch stopwatch = Stopwatch.StartNew();
for (int i = 0; i < iterations; ++i)
action(obj1, obj2);
Console.WriteLine(action.Method.Name + " took " + stopwatch.Elapsed);
}