Interpolation de chaîne vs String.Format

114

Existe-t-il une différence de performances notable entre l'utilisation de l'interpolation de chaîne:

myString += $"{x:x2}";

vs String.Format ()?

myString += String.Format("{0:x2}", x);

Je demande seulement parce que Resharper demande le correctif, et j'ai déjà été dupé.

Krythique
la source
4
Pourquoi ne pas essayer les deux et voir si vous remarquez la différence?
Blorgbeard sort le
57
@Blorgbeard Honnêtement, je suis paresseux. Et je suppose que cela prendrait moins de temps si l'un de vous, hommes / femmes honnêtes, connaissait la réponse de manière désinvolte.
Krythic
26
J'aime le fait que lorsque j'ai posé cette question pour la première fois, elle a été rejetée dans l'oubli et maintenant, deux ans plus tard, c'est jusqu'à +21.
Krythic
47
Sérieusement. Comment douter de l'utilité de cette question? Pouvez-vous imaginer le gaspillage total d'heures de travail, si tous ceux qui posent cette question devaient «l'essayer eux-mêmes et voir»? Même si cela n'a pris que 5 minutes, multipliez ce chiffre parmi les plus de 10000 développeurs qui ont consulté cette question jusqu'à présent. Et ensuite, que faites-vous lorsqu'un collègue doute de vos résultats? Refais le encore? Ou peut-être simplement les renvoyer à ce message SO. C'est en quelque sorte ce pour quoi il est là.
BTownTKD
8
@BTownTKD C'est le comportement typique de Stackoverflow pour vous. Si quelqu'un utilise le site aux fins prévues, il est immédiatement aliéné. C'est aussi l'une des raisons pour lesquelles je pense que nous devrions être autorisés à interdire collectivement les comptes. Beaucoup de gens ne méritent tout simplement pas d'être sur ce site.
Krythic

Réponses:

72

Remarquable est relatif. Cependant: l'interpolation de chaîne est transformée en string.Format()lors de la compilation, donc ils devraient aboutir au même résultat.

Il existe cependant des différences subtiles: comme nous pouvons le constater à partir de cette question, la concaténation de chaînes dans le spécificateur de format entraîne un string.Concat()appel supplémentaire .

Jeroen Vannevel
la source
4
En fait, l'interpolation de chaîne pourrait se compiler en concaténation de chaîne dans certains cas (par exemple, quand a intest utilisé). var a = "hello"; var b = $"{a} world";compile en concaténation de chaînes. var a = "hello"; var b = $"{a} world {1}";compile au format chaîne.
Omar Muscatello
5

l'interpolation de chaîne est transformée en string.Format () au moment de la compilation.

Également dans string.Format, vous pouvez spécifier plusieurs sorties pour un seul argument et différents formats de sortie pour un seul argument. Mais l'interpolation de chaîne est plus lisible, je suppose. C'est à vous de répondre.

a = string.Format("Due date is {0:M/d/yy} at {0:h:mm}", someComplexObject.someObject.someProperty);

b = $"Due date is {someComplexObject.someObject.someProperty:M/d/yy} at {someComplexObject.someObject.someProperty:h:mm}";

Il y a quelques résultats de tests de performance https://koukia.ca/string-interpolation-vs-string-format-string-concat-and-string-builder-performance-benchmarks-c1dad38032a

Paul
la source
2
l'interpolation de chaîne est parfois transformée en String::Format. et parfois dans String::Concat. Et le test de performance sur cette page n'est pas vraiment significatif: la quantité d'arguments que vous passez à chacune de ces méthodes dépend. concat n'est pas toujours le plus rapide, le constructeur de chaînes n'est pas toujours le plus lent.
Matthias Burger
3

La question portait sur les performances, mais le titre dit simplement "vs", donc j'ai le sentiment de devoir ajouter quelques points de plus, certains d'entre eux étant cependant avisés.

  • Localisation

    • L'interpolation de chaîne ne peut pas être localisée en raison de la nature du code en ligne. Avant la localisation, il a été transformé en string.Format. Cependant, il existe des outils pour cela (par exemple ReSharper).
  • Maintenabilité (mon avis)

    • string.Formatest beaucoup plus lisible, car il se concentre sur la phrase que je voudrais exprimer, par exemple lors de la construction d'un message d'erreur agréable et significatif. L'utilisation des {N}espaces réservés me donne plus de flexibilité et il est plus facile de le modifier plus tard.
    • En outre, le spécificateur de format incorporé dans l'interploation est facile à mal interpréter et à supprimer avec l'expression lors d'une modification.
    • Lors de l'utilisation d'expressions complexes et longues, l'interpolation devient rapidement encore plus difficile à lire et à maintenir, donc dans ce sens, elle ne s'adapte pas bien lorsque le code évolue et devient plus complexe. string.Formatest beaucoup moins enclin à cela.
    • En fin de compte, tout est question de séparation des préoccupations: je n'aime pas mélanger la façon dont cela devrait être présenté avec ce qui devrait être présenté .

Donc, sur la base de ceux-ci, j'ai décidé de m'en tenir string.Formatà la plupart de mon code. Cependant, j'ai préparé une méthode d'extension pour avoir une manière plus fluide de coder que j'aime beaucoup plus. L'implémentation de l'extension est une ligne unique, et elle ressemble simplement à ceci en cours d'utilisation.

var myErrorMessage = "Value must be less than {0:0.00} for field {1}".FormatWith(maximum, fieldName);

L'interpolation est une excellente fonctionnalité, ne vous méprenez pas. Mais IMO, il brille le mieux dans les langages qui manquent la string.Formatfonctionnalité -like, par exemple JavaScript.

Zoltán Tamási
la source
Merci d'avoir ajouté à cela.
Krythic le
1
Je ne suis pas d'accord sur la maintenabilité; accordé ReSharper, il est un peu plus facile de faire correspondre les valeurs insérées avec leurs indices correspondants (et vice versa) mais je pense que c'est encore plus de charge cognitive de déterminer si {3}c'est X ou Y, surtout si vous commencez à réorganiser votre format. Exemple Madlibs: $"It was a {adjective} day in {month} when I {didSomething}"vs string.Format("It was a {0} day in {1} when I {2}", adjective, month, didSomething)-> $"I {didSomething} on a {adjective} {month} day"vsstring.Format("I {2} on a {0} {1} day", adjective, month, didSomething)
drzaus
@drzaus Merci d'avoir partagé vos pensées. Vous avez de bons points, mais ce n'est vrai que si nous n'utilisons que des variables locales simples et bien nommées. Ce que j'ai vu assez souvent, ce sont des expressions complexes, des appels de fonction, tout ce qui est mis dans une chaîne interpolée. Avec string.Formatje pense que vous êtes beaucoup moins sujet à ce problème. Mais de toute façon, c'est pourquoi j'ai souligné que c'était mon avis :)
Zoltán Tamási