質問

のかと思っていStringBuilderとんうつくろうと思いました地域で伝えできたらと考えております。

だれを忘れるほコードの読みやすさは、これらは 高速 るのか。

StringBuilder.Append:

StringBuilder sb = new StringBuilder();
sb.Append(string1);
sb.Append("----");
sb.Append(string2);

StringBuilder.AppendFormat:

StringBuilder sb = new StringBuilder();
sb.AppendFormat("{0}----{1}",string1,string2);
役に立ちましたか?

解決

することはできないと言いがわからないサイズの string1string2.

を呼び出 AppendFormat, まpreallocateのバッファ回だされたフォーマット文字列の文字列が挿入され、その後の連結ものと差し込み、バッファです。のための非常に大きな文字列、このことインターネットで提供される以上個別の通話を Append がの原因となるバッファーを拡大す。

しかし、電話 Append れないトリガー成長のバッファやチェックが実施されています。の場合は文字列は小さいなバッファの拡大には、それを可能に AppendFormat でないパフォーマット文字列がないので代替す

より多くのデータが必要な段階では明確にお答え

このあまり議論を利用静的 Concat 方法に String クラス (ジョンの回答 を使用 AppendWithCapacity のオーラという言葉が定着した。試験の結果の場合(ばんの特定のフォーマット指定子). String.Concat も同じことが行われていることでpredetermineの長さの文字列を連結びpreallocateのバッファーとのやや架によるループ構築を通じてのパラメータこの性能を比較することはできジョンの AppendWithCapacity 方法。

は、平野のほか、オペレーターで統を呼び出し String.Concat 鏡の点に注意するすべての追加と同じ表現

// One call to String.Concat.
string result = a + b + c;

ない

// Two calls to String.Concat.
string result = a + b;
result = result + c;

すべての人をコード試験

を実行する必要がありますテストケース 運(または少なくとも、GCの測定個別の試験運行).デジタル化できなかった理由はただ、1,000,000、新規作成 StringBuilder 繰り返し処理毎にループごとに一個の試験は、その次の試験ループの回数、 追加 1,000,000 StringBuilder インスタンスは、GCがありまステップ第二次試験及び妨げ、そのタイミングでした。

他のヒント

casperOneは正しいのです。あなたが特定のしきい値に達すると、Append()方法はAppendFormat()よりも遅くなりました。ここで、異なる長さ及び各方法100,000反復の経過ティックは、次のとおり

長さ:1

Append()       - 50900
AppendFormat() - 126826

長さ:1000

Append()       - 1241938
AppendFormat() - 1337396

長さ:万

Append()       - 12482051
AppendFormat() - 12740862

長20,000

Append()       - 61029875
AppendFormat() - 60483914

2万近い長さの文字列が導入されると、AppendFormat()機能はのわずかのアウトパフォームAppend()ます。

これはなぜ起こるのでしょうか? casperOneの答えを参照してください。

編集

私は、Release構成の下で個別にテストをreranし、結果を更新します。

casperOneが全て正確かつそのデータ.しかし、いまことクラスライブラリのための3者の消費を備えています。

ることが一のぶどのデータをいかにして追加し、その利用 StringBuilder.EnsureCapacity くいだけで単一のバッファサイズ変更.

まん すぎ んが、今までの利用 Append x3う"が"めとして構文解析の文字列形式のトークンの全ての通話は明らかくたくさんありました。

ているので注意してほしいのBCLチームのための一種の"キャッシュされたフォーマッター"まで作成用フォーマット文字列としての再利用を繰り返す。この狂の枠組みを構文解析のフォーマット文字列の各時間で使用します。

編集:大丈夫、私は編集ジョーンズコードや柔軟性に加えて"AppendWithCapacity"の作品だけに必要な能力です。この結果、異なる長さ-長さ1を使って1,000,000回;すべてのその他の長さ使用した100,000.(これだけでも良識ある走ります。) すべての時間でmillis.

残念ながらテーブルやすい仕事です。の長さは1,1000,10000,20000

時間:

  • 追加:162,475,7997,17970
  • AppendFormat:392,499,8541シリーズ,18993
  • AppendWithCapacity:139,189,1558,3085

もしかしながら現実に面したこのAppendFormatビートに追加もっ かった 見AppendWithCapacity選手は非常に充実。

こちらのフルコード:

using System;
using System.Diagnostics;
using System.Text;

public class StringBuilderTest
{            
    static void Append(string string1, string string2)
    {
        StringBuilder sb = new StringBuilder();
        sb.Append(string1);
        sb.Append("----");
        sb.Append(string2);
    }

    static void AppendWithCapacity(string string1, string string2)
    {
        int capacity = string1.Length + string2.Length + 4;
        StringBuilder sb = new StringBuilder(capacity);
        sb.Append(string1);
        sb.Append("----");
        sb.Append(string2);
    }

    static void AppendFormat(string string1, string string2)
    {
        StringBuilder sb = new StringBuilder();
        sb.AppendFormat("{0}----{1}", string1, string2);
    }

    static void Main(string[] args)
    {
        int size = int.Parse(args[0]);
        int iterations = int.Parse(args[1]);
        string method = args[2];

        Action<string,string> action;
        switch (method)
        {
            case "Append": action = Append; break;
            case "AppendWithCapacity": action = AppendWithCapacity; break;
            case "AppendFormat": action = AppendFormat; break;
            default: throw new ArgumentException();
        }

        string string1 = new string('x', size);
        string string2 = new string('y', size);

        // Make sure it's JITted
        action(string1, string2);
        GC.Collect();

        Stopwatch sw = Stopwatch.StartNew();
        for (int i=0; i < iterations; i++)
        {
            action(string1, string2);
        }
        sw.Stop();
        Console.WriteLine("Time: {0}ms", (int) sw.ElapsedMilliseconds);
    }
}

Append には速くになりますほとんどの場合、コンパイラが正しいメソッドを呼び出すことができ、その方法には多くのオーバーロードがありますので。あなたがStringsを使用しているのでStringBuilderStringためAppendオーバーロードを使用することができます。

AppendFormat Stringを取り、その後、フォーマットが解析されなければならないことを意味Object[]、アレイ内の各ObjectはそれがToString'd内部配列に追加することができる前にStringBuilder'sする必要があります。

注: casperOneのポイントへ - より多くのデータをせずに正確な答えを与えることは困難である。

StringBuilderもカスケード接続している追加されますAppend()StringBuilder自身を返しますので、あなたはこのようなコードを書くことができます:

StringBuilder sb = new StringBuilder();
sb.Append(string1)
  .Append("----")
  .Append(string2);

クリーン、そして(それは本当にマイクロ最適化だが)、それはあまりIL-コードを生成します。

もちろん、輪郭のそれぞれの場合に確実に知るために。

私はあなたが繰り返しフォーマット文字列を解析していないので、一般的に、それは、元になると思う、と述べたこと。

しかし、その差は非常に小さくなります。あなたが本当にとにかく、ほとんどの場合、AppendFormatの使用を検討する必要があります。

ポイントへ

私はそれが仕事の最低額をしたコールだったと仮定したいです。ただAppendFormatは、文字列置換を行っている文字列を、連結追加します。もちろん、これらの日、あなたが言うことができませんでし...

2フォーマットに基づいて文字列を作成し、その文字列を追加しなければならないのに対し、それは単純に文字列を付加しているため、

1が速くなければなりません。だから、そこに余分なステップがあります。

の高速化は、しかし、それは公正な比較ではありません、あなたの場合は1です。あなたはStringBuilder.Append(String.Formatの())VS)(StringBuilder.AppendFormatを依頼する必要があります - 最初のものはより速く内部作業のためにchar配列である。ここで、

あなたの目のオプションは、しかし、より読みやすいです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top