8 votes

Quelle est la différence entre ldsfld et ldstr dans IL?

J'ai lu quelques articles sur String.Empty vs "" et j'ai également fait des tests par moi-même. Les différences entre eux sont ci-dessous.

String.Empty

L_0001: ldsfld string [mscorlib]System.String::Empty

""

L_0001: ldstr ""

Après avoir discuté avec mes amis, ils soutiennent que String.Empty est plus rapide que "" car sous le capot (au niveau de l'assembly), ldstr effectue plus de 1 cycle que ldsfld. (Je ne peux pas me rappeler des étapes qui les rendent différentes)

Je veux savoir comment je peux vérifier cet aspect des performances.

13voto

Guffa Points 308133

L'opération ldsfld pousse la valeur d'un champ statique sur la pile d'évaluation, tandis que ldstr pousse une référence à une chaîne de caractères littérale de métadonnées.

La différence de performance (s'il y en a) serait minime. Les nouvelles versions du compilateur remplacent en fait "" par String.Empty.

Vous devriez également considérer la lisibilité et la maintenabilité du code. En utilisant String.Empty, il est plus clair que vous voulez réellement dire une chaîne vide et que vous n'avez pas simplement oublié de saisir quelque chose dans la chaîne littérale.

Éditer:

J'ai jeté un coup d'œil au code natif créé.

C# 3, mode release, x86:

        string a = String.Empty;
0000002a  mov         eax,dword ptr ds:[0356102Ch]
0000002f  mov         dword ptr [ebp-8],eax
        string b = "";
00000032  mov         eax,dword ptr ds:[0356202Ch]
00000038  mov         dword ptr [ebp-0Ch],eax

C# 3, mode release, x64:

        string a = String.Empty;
0000003b  mov         rax,12711050h 
00000045  mov         rax,qword ptr [rax] 
00000048  mov         qword ptr [rsp+28h],rax 
        string b = "";
0000004d  mov         rax,12713048h 
00000057  mov         rax,qword ptr [rax] 
0000005a  mov         qword ptr [rsp+30h],rax 

Ainsi, en fin de compte, le code est identique.

7voto

Jon Skeet Points 692016

ldstr est IL pour charger un jeton de chaîne spécifique à partir des métadonnées.

ldsfld est IL pour charger le champ spécifié - qui dans ce cas est string.Empty.

En d'autres termes, ce sont des opérations entièrement différentes, qui ont le même résultat dans ce cas. Comment sont-elles implémentées au niveau de l'assemblage? Eh bien, cela pourrait très bien dépendre de la version du CLR que vous utilisez. Demandez à vos amis de quelle version ils parlent... bureau (32 ou 64 bits? 1, 2, 2SP1, 2SP2, 4?), Compact Framework (encore une fois, quelle version?), Silverlight (quel système d'exploitation, quelle version?) Ont-ils utilisé cordbg sur le code que vous discutez réellement, ou l'ont-ils fait sur un code d'exemple, qui n'a peut-être pas été optimisé de la même manière?

Je soutiendrais (et l'ai fait) que vous devriez utiliser celui que vous trouvez le plus lisible. Personnellement, je préfère "" mais d'autres préfèrent string.Empty. C'est bien. Argumenter pour l'un plutôt que pour l'autre pour des raisons de performance nécessite des preuves cependant... et idéalement, des preuves basées sur le code que vous écrivez réellement, et non sur un micro-benchmark.

Je serais étonné de voir du code où toute différence entre les deux entraîne réellement une différence de performance significative dans du code réel - autre que dans des situations où il y a probablement une meilleure façon d'aborder la tâche de toute façon.

7voto

Marc Gravell Points 482669

À partir de .NET 4.5, la différence dans ce cas est : exactement rien. Il semble que le JIT détecte désormais ce ldsfld et injecte directement la chaîne vide internée.

Vous pouvez le constater car dans < 4.5, vous pouvez changer la valeur de string.Empty via la réflexion et cela affecte le code utilisant string.Empty. Désagréable mais possible. À partir de 4.5, cela ne fonctionne plus. Si vous pouvez vérifier via la réflexion, vous obtenez la version piratée, mais le code utilisant string.Empty via ldsfld obtient la chaîne vide correcte plutôt que la version piratée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X