Question

fonctionne-t-chaîne immuabilité par déclaration, ou par des chaînes dans une déclaration?

Par exemple, je comprends que le code suivant attribuera deux chaînes sur le tas.

string s = "hello ";
s += "world!";

« bonjour » restera sur le tas jusqu'à ce que les déchets collectés; et s maintenant des références « Bonjour tout le monde! » sur le tas. Cependant, combien de chaînes ne la ligne suivante allouer sur le tas ... 1 ou 2? Aussi, est-il un outil / moyen de vérifier les résultats?

string s = "goodbye " + "cruel world!";
Était-ce utile?

La solution

Le compilateur a un traitement spécial pour la concaténation de chaîne, qui est la raison pour laquelle le second exemple est que jamais une chaîne . Et « interné » signifie que même si vous exécutez cette ligne 20000 fois il reste seulement 1 chaîne.

Re tester les résultats ... la meilleure façon (dans ce cas) est probablement regarder dans le réflecteur:

.method private hidebysig static void Main() cil managed
{
    .entrypoint
    .maxstack 1
    .locals init (
        [0] string s)
    L_0000: ldstr "goodbye cruel world!"
    L_0005: stloc.0 
    L_0006: ldloc.0 
    L_0007: call void [mscorlib]System.Console::WriteLine(string)
    L_000c: ret 
}

Comme vous pouvez le voir (ldstr), le compilateur a fait pour vous déjà.

Autres conseils

Les chaînes littérales sont internées cela signifie que le fait "hello " pas résider sur le tas, mais dans le segment de données [voir commentaire] du progamme (et est donc pas admissible à la collecte des ordures), même pour "world", comme pour qui peut "hello world" également être interné, si le compilateur est assez intelligent.

"goodbye cruel world" être interné depuis concaténation de chaîne littérale est quelque chose traitée par le compilateur.


Modifier Je ne suis pas sûr de la déclaration de segment de données, s'il vous plaît voir cette question pour plus d'informations.

En fait, probablement 3. une chaîne const pour « au revoir », une chaîne const pour « monde cruel », puis une nouvelle chaîne pour le résultat.

Vous trouverez à coup sûr en regardant le code généré. Cela dépend du compilateur, (et, en fait, la langue, ce n'est pas évident) mais vous pouvez lire la sortie de g ++ en utilisant l'option -a (je pense, vérifier la page de manuel) pour obtenir le code intermédiaire .

Ne faites pas confiance à ce que vous « savez » sur les chaînes. Vous pouvez regarder dans le code source pour la mise en œuvre de la chaîne. Par exemple votre exemple:

string s = "goodbye " + "cruel world!";

En java allouerait une seule chaîne. Java joue quelques trucs assez mignon et serait difficile à déjouer - tout simplement jamais optimiser jusqu'à ce que vous devez

À l'heure actuelle cependant, pour autant que je sache, en utilisant ceci:

String s="";
for(int i=0;i<1000;i++)
    s+=" ";

pour créer une chaîne de l'espace 1000 a encore tendance à être extrêmement inefficace

dans une boucle Adjonction est assez mauvaise, mais sinon il est probablement aussi efficace que StringBuilder.

Faites attention ici, parce que le compilateur peut faire quelques optimisations très différentes lorsque les valeurs de chaîne sont connues au moment de la compilation. Si les chaînes que vous utilisez ne sont pas connus jusqu'à ce que l'exécution (tiré à partir d'un fichier de configuration, base de données, ou l'entrée d'utilisateur), vous verrez une très différente IL.

Si vous allez juste faire un ou deux concaténations de chaînes, je ne vous inquiétez pas.

Toutefois, si vous avez beaucoup de concaténations, ou si vous avez une boucle, alors vous avez certainement envie de prendre des précautions. Dans le monde Java qui signifie que vous utilisez insteads StringBuffer de chaîne concaténer.

Si ce n'est pas seulement dans une ligne, la concaténation de deux chaînes peut être accompli en faisant la première chaîne en un StringBuffer, en faisant la concaténation, et retourner la chaîne de résultat.

Création du StringBuffer vous-même peut sembler exagéré, mais c'est ce qui va se passer de toute façon .-

Par tous les moyens ne sont pas optimiser prématurément, mais ne négligez pas comment concatonations mal de cordes peuvent être performants. Ce n'est pas la création d'objets, mais le travail de GC qu'il provoque.

Il y a un laboratoire sur (ASP.NET Escalation Ingénieur) Blog Tess Ferrnandez qui montrent est un par exemple (plutôt extrême, accordée) de comment concatonation chaîne peut apporter un serveur à genoux .

Si le compilateur est « intelligent », il ne sera une chaîne avec « au revoir monde cruel! »

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top