7
votes

Performance créant des chaînes concaténées

Quel moyen de créer des chaînes est plus efficace d'exécution efficace dans C # code>

Number 1: strong> p>

bool value = true;
String channel = "1";
string  s = ":Channel" + channel + ":Display " + value ? "ON" : "OFF";


13 commentaires

Je me rends compte que je demande une chose presque impossible, mais pourquoi n'avez-vous pas essayé de vous mesurer?


Avez-vous identifié cela comme un problème de performance? Choisissez le format plus lisible (iMo )


Pourquoi les bowvotes? C'est une question décente (même si vous pouviez le mesurer vous-même; OTOH, cela pourrait aider les autres)


Notez que la première version commence par un côlon; le second ne le fait pas.


@Bart Friederichs: Les problèmes de performance n'ont souvent rien de commun. C'est souvent une mauvaise idée d'essayer de résoudre vos propres problèmes de performance après les solutions des autres, juste parce que même une infime différence dans l'environnement peut apporter une énorme différence de résultats.


Non, n'avez pas de problème de performance. Je sais que la préoptimisation est la racine de tout mal. Mais je viens d'autres quincailleries où la performance est rare. Si je mettant en œuvre quelque chose de nouveau, peu importe si je le fais de cette façon ou de cette façon - je peux donc le faire correctement la première fois. Tous les changements sont ensuite nul ...


Bonjour Razor, je ne participerai pas à la discussion, mais ce lien peut vous donner quelques indications qui s'appromettent de l'utilisation lorsque: geekswithblogs.net/blackrabbitcoder/archive/2010/05/10/...


Dans la plupart des codes, tout ira bien; Le premier a une certaine analyse supplémentaire, mais quand j'ai testé cela, l'analyse est si rapide qu'elle n'a tout simplement pas d'impact sur les résultats. La première approche sera beaucoup plus facile d'internationaliser / localisera si vous en avez besoin. La seconde a moins analysé, mais un coût d'entretien plus élevé (plus délicat à l'internationalisation, etc.).


L'option 2 ne compile même pas


@Dgibbs true; Je suppose que cela devrait être string s = ": canal" + canal + ": affiche" + (valeur? "ON": "OFF");


DUPLICATES POSSIBLES: Stackoverflow.com/Questions/296978/... et Stackoverflow.com/Questtions/16432/...


C'est une question qui a été posée des dizaines de fois. Stackoverflow.com/ Questions / 21078 / ... donne une bonne vue d'ensemble et heuristique avec laquelle choisir.


Le premier est de bien meilleure quelle que soit sa performance: la première technique vous permet d'isoler la chaîne dans une ressource localisable .


4 Réponses :


6
votes

Cela pourrait vous aider à tester cela vous-même. Ceci a été exécuté à l'aide de .NET V4.0.30319 Runtime.

sw = new System.Diagnostics.Stopwatch();

// Number 1
bool value = true;
int channel = 1;
sw.Start();
for (int i = 0; i <= 100000; i++)
{
    String s = String.Format(":Channel{0}:Display {1}", channel, value ? "ON" : "OFF");
}
sw.Stop();

sw.Reset();

// Number 2
sw.Start();
for (int i = 0; i <= 100000; i++)
{
    string s = "Channel" + channel + ":Display " + (value ? "ON" : "OFF");
}
sw.Stop();


6 commentaires

Personnellement, je ne fais pas que 16 ms vs 12ms est clair suffisamment coupé, étant donné la précision du calendrier


@Marcgravell: Désolé, alors que vous écriviez ce commentaire, j'ajoutiais un autre exemple avec 100 000 itérations.


C'est plus comme ça;) Maintenant tout ce que vous avez à faire est de le gérer sur la version exact (sous-) version exact (sous-), la version (sous-), et le matériel exact, sous exactement les mêmes conditions de charge de l'arrière-plan ... (OK , Je taquine maintenant)


@Marcgravell: IMHO Le résultat semble être assez concluant pour le même point d'exécution .NET. Les temps d'exécution peuvent passer de la machine à la machine, mais la 2e option est plus efficace (au moins du point de vue de l'exécution de temps) en tenant compte de la grande différence montrée sur mon test.


En effet; Et comme je l'ai déjà dit - c'est beaucoup mieux avec ces chiffres; Le 12 vs 16 ... pas très concluant


@MARC Gravell: D'accord, retiré pour éviter les confusions. Merci pour les commentaires!



-4
votes

numéro 1 est le plus efficace.

String.Format () fonction utilise System.Text.StringBuilder de type interne pour des chaînes de concaténation.

Le StringBuilder est utilisé pour représenter une chaîne mutable (aka éditable) et c'est le moyen le plus efficace de conciser des chaînes. http://msdn.microsoft.com/en-us/library /system.text.stringbuilder.aspx .


7 commentaires

que le raisonnement est incomplet; La deuxième version utilise string.concat , qui est aussi fortement optimisé. En conséquence, encore plus, puisqu'il utilise une approche rapide et écrase, plutôt qu'un tampon de support redimensionné. Si c'était une boucle, alors sûr: stringbuilder gagnerait la main vers le bas. Pour une concision à une seule ligne: non; string.concat est l'approche la plus appropriée, qui peut être faite à l'aide du code indiqué dans l'exemple 2ème exemple.


De MSDN Utilisez la classe de chaîne si Vous concatéez un nombre fixe d'objets de chaîne. Dans ce cas, le compilateur peut même combiner des opérations de concaténation individuelles en une seule opération.


Votre édition rend cette réponse pire et activement incorrecte. Désolé, mais je ne pense pas que vous comprenez comment le compilateur traite le 2e exemple. Astuce: Ce n'est pas ce que vous décrivez.


C'est l'exemple du Guide Microsoft d'utiliser string.concat (): "... Lorsque la performance est importante, vous devez toujours utiliser la classe StringBuilder pour concaténer des chaînes. ..." msdn.microsoft.com/en-us/library/ms228504.aspx


En règle générale, StringBuilder n'est que plus efficace dans les cas où vous concatéez de très grandes chaînes, ou un très grand nombre de cordes, peut-être à l'intérieur d'une boucle. Quelque chose comme "bonjour" + "monde" va bouillir à string.concat qui est bien mieux adapté à ce scénario puisque nous connaissons déjà la taille des chaînes avant de compiler l'heure et n'a pas besoin de redimensionnement dynamique que StringBuilder fournit


@Georgiigonchara recherche de la page pour "Même si vous utilisez plusieurs opérateurs + dans une seule déclaration, le contenu de la chaîne est copié une seule fois."; Ce que vous dites est vrai que lorsqu'il y a plusieurs déclarations. Ici, il n'y en a qu'un. Désolé, votre exemple est incorrect et ne s'applique pas ici.


@Marcgravell d'accord avec votre point. Je n'ai pas compris la question correctement et j'ai répondu trop tôt. Leçon apprise.



7
votes

Je vais ajouter un exemple maintenant pour illustrer la manière dont le compilateur traite les deux, car il semble y avoir un lot em> fort> de confusion dans certaines des autres réponses (EDIT: Notez que beaucoup de ces confusions ont été supprimées / éditées):

string s = string.Concat(":Channel", channel, ":Display ", value ? "ON" : "OFF");


0 commentaires

0
votes

Concernant la réponse de Marc Gravell: vous pouvez éviter l'opération de boxe en passant par Channel.tostring (). J'ai vérifié comme éthériquement que cela donne une légère amélioration des performances pour les deux n ° 1 et n ° 2.

  • Dans le cas de l'affaire 1, vous évitez l'opération de boxe.
  • Dans le cas où n ° 2, vous évitez d'appeler l'opérateur de conversion implicite.

    Mais après avoir essayé de réfuter votre théorie (avec des concatenations plus longues et des cordes aléatoires), je dois concéder que # 2 est plus rapide que n ° 1.


0 commentaires