Інтерполяція рядків проти String.Format


113

Чи є помітна різниця в продуктивності між використанням інтерполяції рядків:

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

vs String.Format ()?

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

Я прошу лише тому, що Resharper спонукає до виправлення, і мене раніше обдурили.


4
Чому б не спробувати обидва і подивитися, чи помітили ви різницю?
Blorgbeard виходить

57
@Blorgbeard Чесно кажучи, я лінивий. І я вважаю, що це займе менше часу, якби хтось із вас поважних чоловіків / жінок знав відповідь не з чужих.
Критичний

26
Мені подобається, як коли я вперше поставив це запитання, воно прийшло до забуття, і тепер, через два роки, це до +21.
Критичний

46
Серйозно. Як хто може сумніватися в корисності цього питання? Чи можете ви уявити загальну витрату годин на людину, якщо всі, хто задає це питання, повинні були "спробувати самі і подивитися?" Навіть якщо це займе лише 5 хвилин, помножте це на 10 000+ розробників, які досі переглядали це питання. І що тоді робити, коли колега сумнівається у своїх результатах? Зроби це все заново? Або, можливо, просто віднесіть їх до цієї публікації SO. Ось це щось таке.
BTownTKD

8
@BTownTKD Це типова для вас поведінка Stackoverflow. Якщо хтось використовує сайт за призначенням, його негайно відчужують. Це також одна з причин, чому я вважаю, що нам слід дозволити колективно забороняти рахунки. Багато людей просто не заслуговують на те, щоб бути на цьому сайті.
Критичний

Відповіді:


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. І тест ефективності на цій сторінці не дуже важливий: кількість аргументів, які ви передаєте кожному з цих методів, залежить. 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.


Дякуємо, що додали до цього.
Критичний

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Я думаю , ви набагато менш схильні до цього питання. Але все одно, саме тому я підкреслив, що це моя думка :)
Zoltán Tamási,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.