文字列補間とString.Format


113

文字列補間の使用には顕著なパフォーマンスの違いがありますか?

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

vs String.Format()?

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

Resharperが修正を促しているため、私は質問しているだけで、以前はだまされていました。


4
両方を試して、違いに気づいたかどうかを確認してみませんか?
Blorgbeardは2015

57
@Blorgbeard正直なところ、私は怠惰です。そして、正直な男性/女性の1人が答えを手元で知っていれば、より少ない時間で済むと思います。
Krythic

26
私が最初にこの質問をしたとき、それが忘却に反対票を投じられたのが好きで、2年後の今、それは最大+21です。
Krythic

46
真剣に。どうすればこの質問の有用性を疑うことができますか?この質問をするすべての人が「自分で試して見なければならない」としたら、人の時間を浪費することを想像できますか?5分しかかからない場合でも、これまでにこの質問を見てきた10,000人以上の開発者を掛け合わせてください。そして、同僚があなたの結果を疑うとき、あなたは何をしますか?もう一度やり直しますか?または、このSOの投稿を参照してもらってください。それはそれが何のためにあるのかということです。
BTownTKD 2017年

8
@BTownTKDこれは、典型的なStackoverflowの動作です。意図された目的でこのサイトを使用した人は、すぐに疎外されます。これも、一括してアカウントを禁止することを認められるべき理由の一つです。多くの人々は単にこのサイトにいるに値しない。
Krythic 2017年

回答:


72

注目すべきは相対的です。ただし、文字列補間はstring.Format()コンパイル時に変換されるため、結果は同じになります。

ただし、微妙な違いがあります。この質問からわかるように、書式指定子での文字列連結は追加のstring.Concat()呼び出しになります。


4
実際、文字列補間は、場合によっては(たとえば、a intが使用されている場合)、文字列連結にコンパイルされる可能性があります。 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は常に最速であるとは限らず、stringbuilderが常に最低速であるとは限りません。
Matthias Burger

3

問題はパフォーマンスに関するものでしたが、タイトルは「vs」とだけ書かれているので、もう少しポイントを追加する必要があるように感じます。

  • ローカリゼーション

    • インラインコードの性質上、文字列補間はローカライズできません。ローカライズ前は、になってい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}。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"string.Format("I {2} on a {0} {1} day", adjective, month, didSomething)
drzaus

@drzausご意見をお寄せいただきありがとうございます。良い点がありますが、それは、単純で適切な名前のローカル変数のみを使用する場合にのみ当てはまります。私が何度も目にしたのは、複雑な式、関数呼び出しなど、補間された文字列に入れられるものです。とstring.Format私はあなたがこの問題を起こしにくいと思います。私はそれが私の意見だと強調した理由しかし、いずれにせよ、これは:)
ゾルタンTamási
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.