7

文字列を作成するどの方法がより実行時間効率がよいかC#

番号 1:

bool value = true;
int channel = 1;
String s = String.Format(":Channel{0}:Display {1}", channel, value ? "ON" : "OFF");

2番:

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

4 に答える 4

7

コンパイラが2つをどのように扱うかを説明するために、例を追加します. :

bool value = true;
int channel = 1;
String s = String.Format(":Channel{0}:Display {1}", channel,
    value ? "ON" : "OFF");

最後の行は次のようにコンパイルされます。

String s = String.Format(":Channel{0}:Display {1}",
    new object[2] {(object)channel, value ? "ON" : "OFF")};

興味深いことに、 の配列と「ボックス」の作成、および/int channelを見つけるために必要な追加の解析に注意してください。{0}{1}

今ナンバー2:

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

最後の行は次のようにコンパイルされます。

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

ここには、配列もボックスもありません (channelは文字列になりました)、解析もありません。オーバーロードはpublic static string string.Concat(string,string,string,string); string.Concat適切なサイズの文字列を事前に割り当ててから上書きするなど、非常に効率的に実装されます。

ほとんどのコードでは、どちらでもかまいません。2 番目のバージョンは、技術的にはより効率的 (ボックスなし、配列なし、解析なし) ですが、後で国際化する場合は大きな問題になります。ほとんどのアプリケーションでは、この 2 つの違いに気付くことはありません。解析は高速で、ボックス/配列はジェネレーション ゼロ オブジェクトとして安価に収集されます。しかし、安いことはタダではありません。

于 2013-03-10T22:03:57.840 に答える
6

これは、これを自分でテストするのに役立ちます。これは、.net v4.0.30319 ランタイムを使用して実行されました。

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();

私の結果は次のとおりです。

番号 1: 136ms

数 2: 91ms

したがって、2 番目のオプションの方がパフォーマンスが優れています。最初のオプションが追加のメソッド呼び出し ( string.Format()) を使用し、パラメータを置き換える (Marc が指摘したように) という事実が違いを生んでいます。

100.000 反復を使用する代わりに 1.000.000 を使用すると、これが得られます

番号 1: 1308ms

数 2: 923ms

基本的に同じ結論。

于 2013-03-10T21:43:15.337 に答える
0

Marc Gravell の回答について: channel.ToString() を渡すことで、ボックス化操作を回避できます。これにより、#1 と #2 の両方のパフォーマンスがわずかに向上することを経験的に確認しました。

  • ケース #1 では、ボックス化操作を回避します。
  • ケース #2 では、暗黙的な変換演算子の呼び出しを回避します。

しかし、(より長い連結とランダムな文字列を使用して) あなたの理論を反証しようとした後、#2 が #1 よりも高速であることを認めなければなりません。

于 2014-05-28T14:18:55.377 に答える
-4

1 番が最も効率的です。

String.Format() 関数は、文字列を連結するために System.Text.StringBuilder 型を内部的に使用します。

StringBuilder は、変更可能な (編集可能な) 文字列を表すために使用され、文字列を連結する最も効率的な方法です。http://msdn.microsoft.com/en-us/library/system.text.stringbuilder.aspx

于 2013-03-10T21:47:36.430 に答える