Examiner le programme simple suivant:
using System;
using System.Diagnostics;
class Program
{
private static void Main(string[] args)
{
const int size = 10000000;
var array = new string[size];
var str = new string('a', 100);
var sw = Stopwatch.StartNew();
for (int i = 0; i < size; i++)
{
var str2 = new string('a', 100);
//array[i] = str2; // This is slow
array[i] = str; // This is fast
}
sw.Stop();
Console.WriteLine("Took " + sw.ElapsedMilliseconds + "ms.");
}
}
Si je l'exécute, il est relativement rapide. Si je décommentez la "lenteur" de la ligne et de commenter le "rapide" de la ligne, c'est plus de 5 fois plus lent. Notez que dans les deux situations, il initialise la chaîne "str2" à l'intérieur de la boucle. Ce n'est pas optimisé à l'écart dans les deux cas (ce qui peut être vérifié en regardant l'IL ou du démontage).
Le code semble être en train de faire la même quantité de travail dans les deux cas. Il a besoin d'allouer/initialiser une chaîne de caractères, et ensuite attribuer une référence à un tableau de l'emplacement. La seule différence est de savoir si cette référence est le local var "str" ou "str2".
Pourquoi faut-il faire une telle grande différence de performance attribution de la mention "str" vs "str2"?
Si l'on regarde le démontage, il y a une différence:
(fast)
var str2 = new string('a', 100);
0000008e mov r8d,64h
00000094 mov dx,61h
00000098 xor ecx,ecx
0000009a call 000000005E393928
0000009f mov qword ptr [rsp+58h],rax
000000a4 nop
(slow)
var str2 = new string('a', 100);
00000085 mov r8d,64h
0000008b mov dx,61h
0000008f xor ecx,ecx
00000091 call 000000005E383838
00000096 mov qword ptr [rsp+58h],rax
0000009b mov rax,qword ptr [rsp+58h]
000000a0 mov qword ptr [rsp+38h],rax
La "lenteur" de la version a deux "mov" opérations où le "rapide" version a "nop".
Quelqu'un peut-il expliquer ce qui se passe ici? Il est difficile de voir comment les deux extra mov opérations peuvent entraîner une >5x ralentissement, surtout depuis que j'attendrais la plupart du temps doit être dépensé dans la chaîne d'initialisation. Merci pour toutes les suggestions.