Строковая интерполяция против String.Format

114

Есть ли заметная разница в производительности между использованием интерполяции строк:

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

против String.Format ()?

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

Я спрашиваю только потому, что Resharper предлагает исправить, а меня раньше обманывали.

Krythic
источник
4
Почему бы не попробовать оба и посмотреть, заметите ли вы разницу?
Blorgbeard выйдет
57
@Blorgbeard Честно говоря, я ленив. И я полагаю, что на это ушло бы меньше времени, если бы один из вас, достойных мужчин / женщин, знал ответ на этот вопрос.
Krythic
26
Мне нравится, как, когда я впервые задал этот вопрос, он был забыт, и теперь, два года спустя, он вырос до +21.
Krythic
47
Шутки в сторону. Как можно сомневаться в полезности этого вопроса? Можете ли вы представить себе, сколько человеко-часов потрачено впустую , если бы каждый, задающий этот вопрос, «попробовал сам и увидел»? Даже если это заняло всего 5 минут, умножьте это на 10 000+ разработчиков, которые до сих пор просматривали этот вопрос. А что делать, если коллега сомневается в ваших результатах? Делать все это снова? Или, может быть, просто отсылайте их к этому сообщению SO. Вот для чего он нужен.
BTownTKD
8
@BTownTKD Это типичное для вас поведение Stackoverflow. Если кто-то использует сайт по прямому назначению, он немедленно отчуждается. Это также одна из причин, почему я считаю, что нам следует разрешить коллективно банить учетные записи. Многие люди просто не заслуживают быть на этом сайте.
Krythic

Ответы:

72

Заметное относительное. Однако: строковая интерполяция включается во время string.Format()компиляции, поэтому они должны иметь тот же результат.

Однако есть тонкие различия: как мы можем понять из этого вопроса, конкатенация строк в спецификаторе формата приводит к дополнительному string.Concat()вызову.

Йерун Ванневель
источник
4
Фактически, в некоторых случаях интерполяция строк может скомпилироваться в конкатенацию строк (например, когда intиспользуется a ). var a = "hello"; var b = $"{a} world";компилируется в конкатенацию строк. var a = "hello"; var b = $"{a} world {1}";компилируется в строковый формат.
Омар Мускателло
5

строковая интерполяция превращается в string.Format () во время компиляции.

Также в string.Format вы можете указать несколько выходных данных для одного аргумента и разные форматы вывода для одного аргумента. Но я думаю, строковая интерполяция более читабельна. Так что решать вам.

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}";

Есть некоторые результаты теста производительности https://koukia.ca/string-interpolation-vs-string-format-string-concat-and-string-builder-performance-benchmarks-c1dad38032a

Павел
источник
2
строковая интерполяция просто иногда превращается в String::Format. а иногда и в String::Concat. И тест производительности на этой странице, imho, на самом деле не имеет смысла: количество аргументов, которые вы передаете каждому из этих методов, зависит от него. concat не всегда самый быстрый, построитель строк не всегда самый медленный.
Маттиас Бургер,
3

Вопрос касался производительности, однако в названии просто написано «против», поэтому я чувствую, что нужно добавить еще несколько пунктов, хотя некоторые из них являются самоуверенными.

  • Локализация

    • Строковую интерполяцию нельзя локализовать из-за ее встроенного кода. Перед локализацией он был преобразован в string.Format. Однако для этого есть инструменты (например ReSharper).
  • Ремонтопригодность (мое мнение)

    • string.Formatгораздо более читабелен, поскольку он фокусируется на предложении, которое я хотел бы сформулировать, например, при создании красивого и значимого сообщения об ошибке. Использование {N}заполнителей дает мне больше гибкости, и ее легче изменить позже.
    • Кроме того, встроенный спецификатор формата при интерполяции легко неверно прочитать и легко удалить вместе с выражением во время изменения.
    • При использовании сложных и длинных выражений интерполяцию становится еще труднее читать и поддерживать, поэтому в этом смысле она плохо масштабируется, когда код развивается и становится более сложным. string.Formatгораздо менее подвержен этому.
    • В конце концов, все дело в разделении проблем: мне не нравится смешивать то, как это должно быть представлено с тем, что должно быть представлено .

Исходя из этого, я решил придерживаться string.Formatбольшей части своего кода. Однако я подготовил метод расширения, чтобы иметь более плавный способ кодирования, который мне нравится больше. Реализация расширения однострочная, и при использовании она выглядит просто так.

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

Не поймите меня неправильно, интерполяция - отличная функция. Но IMO он лучше всего проявляет на тех языках, в которых отсутствует string.Format-подобная функция, например JavaScript.

Золтан Тамаши
источник
Спасибо за добавление к этому.
Krythic,
1
Я бы не согласился с ремонтопригодностью; предоставлено, что ReSharper несколько упрощает сопоставление вставленных значений с их соответствующими индексами (и наоборот), но я думаю, что еще большая когнитивная нагрузка - выяснить, {3}X или Y, особенно если вы начнете перестраивать свой формат. Пример 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 Спасибо, что поделились своими мыслями. У вас есть хорошие моменты, но это правда, только если мы используем только простые локальные переменные с хорошо названными именами. То, что я видел довольно много раз, - это сложные выражения, вызовы функций, все, что помещается в интерполированную строку. С string.FormatЯ думаю , вы гораздо менее склонны к этому вопросу. Но в любом случае именно поэтому я подчеркнул, что это мое мнение :)
Золтан Тамаши