私のための文字列のプログラマは、文字列連結の数が存在している実際の開発プロセスで実現し、文字列の常連が、あなたは彼がラインに不慣れではないかわからない、文字列の連結が一般的である一日を満たしています方法は?作品は波を学ぶために、通信するために、話を一緒にしましょう。おそらく、あなたは必ずしも方法、我々はそこに右の最善の方法を使用して、まあ、あまりにも簡単です誰がああ、ハハ、本当に簡単に使用することはないだろうが、ないこと、と言うのだろうか?
概念を理解しなければならない文字列を格納するデータの種類についての記事の前に、我々は簡単にトーク:
文字列は、参照型で密封されたクラスである、ヒープ上に格納され、すべての新しい変更が自動的に回収された原稿を格納するための新しい文字列を作成します。これは、誰もがよく、ハッハッハを知って、気持ちがナンセンスではありません。
次の4つの一般的な方法列のモザイク:C#言語の下には、開発のために説明します
直接縫い合わせてまず、+
直接ステッチまでは、分析にコードのシンプルな作品を以下の、我々のコード+最も一般的な方法です
文字列str = "1";
STR = STR + "2";
最初のコード、値が「1」であるSTR変数を格納するために割り当てられた最初のメモリ空間
コードの2番目の段落は、「12」を格納するための新しいメモリ空間を再割り当てし、新たなアドレスSTRを指します
分析を通じて、我々は実際には、簡単なコードの両端に、アドレスの文字列連結の数と、操作の倍のメモリ・アドレスがあることを見つけ、割り当てられたメモリアドレスの数も増加されたときにいくつかの簡単な文字列スプライシングを経て、実際には、我々はまだ感じたときに、パフォーマンスに影響を与えないが、文字列の数が多い、あなたが感じているだろうと、そのメモリがないだけ無駄ですが、また直接性能に影響を与えます。
だから、+文字列連結によって、実際の開発プロジェクト、では比較的一般的な、しかし、この方法では、あなただけののこぎりもとてもフレンドリーではなく、非友好的なことから、その後、明らかにここで我々の分析、より友好的な方法の友人があるだろうかのStringBuilderので文字列の連結を実装します。
第二に、文字列を縫い合わせることでのStringBuilder
StringBuilderの事実は、内部メンテナンスに対応する文字列が動的データ自体の長さを増やすことができ、格納された文字列の長さを超える16、デフォルトの長さが自動的に拡張の長さの2倍です。
ハハ、そういえば、あなたは問題を見て、それが自動拡張の長さを超えていると思います、自動拡張は、いくつかの拡張は、あなたはまだ、パフォーマンスに影響を与えていないと感じています、しかし、それはまた、当然のことながら、パフォーマンスを犠牲にする必要はない単語数以上であれば、あなたは、これはまた、いくつかのヒントのStringBuilderで、明らかに感じるでしょう。
私たちは、StringBuilderの時間を初期化し、あなたはその技術のベテランを見つけるだろう、コードの異なるジュニアパートナーに行ってきました細部のギャップに反映されているのStringBuilderの長さを、初期化するために、文字列のサイズの推計によると保存されます。
彼は、それはナンセンスを話していないことを証明するために半日のナンセンスは、実際のコードに来てされていないと述べましたか?そして、不安にならない、前回の記事では、私は、特にテストコードの比較分析を書きます。
それに慣れていない第三に、String.Formatの
いくつかの形式のデータ登録の塗りつぶしで、String.Formatのがしばしば見られ、彼は、大きな利点があるのですが比較的明確に見えます
実際には、我々は根本的な本質はStringBuilderのを達成することであることがわかります根底にある文字列の実現を見てきました
ここでString.Formatのを達成するためのソースコードがあります
パブリック 静的の文字列フォーマットは、(するIFormatProviderプロバイダー、文字列の形式は、paramsは <BR>オブジェクト[]引数)を{ 場合(フォーマット== nullの ||引数== nullの) スロー 新しい例外ArgumentNullException((フォーマット== nullの)?" 形式を":" 引数" ); StringBuilderのSB = 新しい StringBuilderの(format.Length + args.Length * 8 )。 sb.AppendFormat(プロバイダ、フォーマット、引数)。 リターンsb.ToString(); }
実際、String.Formatのは、私たちは、ハッハッハ、疲れを感じることはありません長いったらしい導入では、ので、使用するのは簡単です
文字列の結果= String.Formatの( "こんにちは誰もが、私の名前は{0}、{1}は今年で"、 "達人プログラマーツアー"、1);
第四に、$モードの文字列の連結
C#6.0が、$文字列連結の方法は、実際には、あまりにも多くの文字列の連結は、自分自身をリッピングすると推定されている場合、それは単にString.Formatの流線操作バージョン、String.Formatのある対応関係を伝えることを余儀なくされた場合には、あなたが知っていませんとにかく、なしで生きることを、私は前に遭遇していました。良いの$は次の例が示すには、すべての顔をこの問題を回避します:
string name = "程序员修炼之旅";
int age = 1;
string str = string.Format("my name is{0}, I'm {1} years old",name,age);
string str2 = $"my name is{name}, I'm {age} years old";
最终结果是:str=str1
第五には、当然のことながら、他の方法ではなく、この長いったらしいで、フォローアップの議論があります
テストの分析
長い時間が、ない何かが、私はあなたがテストコードに直接以下、納得していないことを知っているいくつかの実際のテストを取得するために言いました:
使用してシステムを、 使用したSystem.Diagnosticsを、 使用してSystem.Textのを、 名前空間stringSplicingTest { /// <要約> /// 文字列連結の練習 /// </要約> パブリック クラスプログラム { /// <要約> /// メイン関数エントリ /// </要約> /// <PARAM NAME = "引数"> </ PARAM> 静的 ボイドメイン(文字列[] argsが) { // テストは、0 +とのStringBuilder番号100を介して接続されている コンソール.WriteLine("試験のStringBuilder +によって接続されています。" ); Console.WriteLineを(" " ); Console.WriteLineを(" 0から接続テスト- 100 " ); Console.WriteLineを(" " ); PlusString(100 ); StringBuilderString2(100 ); Console.WriteLineを(" " ); Console.WriteLineを("" ); Console.WriteLineを(" 0から接続テスト- 10000 " ); PlusString(万); StringBuilderString2(万); Console.WriteLineを(「」); Console.WriteLineを(「」); // 次のテストも接続されているStringBuilderの文字列は、比較は、長さ指定されていない場合、指定された長さを食べるために定義されている (Console.WriteLineをし@ " 試験を以下StringBuilderの同じ接続文字列、定義され、指定された長さ、比較が長さを指定されていない「); Console.WriteLineを(」「); Console.WriteLineを(」0から接続テスト- 1000000 " ); Console.WriteLineを(" ない初期長さ" ); StringBuilderString(1000000 ); Console.WriteLineを("初期長」); StringBuilderString2(1000000 ); Console.WriteLineを("" ); Console.WriteLineを("" ); Console.WriteLineを(" 接続テスト0 - 10,000,000番号" ); Console.WriteLineを(" しない初期長さ" ); StringBuilderString (10000000 ); Console.WriteLineを(" 初期長さ" ); StringBuilderString2(10000000 ); Console.ReadLine(); } /// <まとめ> /// 文字列連結によって+ /// </要約> /// <名前= "totalnum" param>の</ PARAM> プライベート 静的 ボイド PlusString(INT totalnum) { /// /ストップウォッチを定義し、アクセスの実装を行います時間 ザ・ストップウオッチST = 新しい新ザ・ストップウォッチ(); // インスタンス化クラス st.Start(); // 開始時期 (Console.WriteLineをする" 接続文字列+を通じて、開始:" ); 文字列の結果= "" ; /// /アレイを定義 するための(INT I = 0を; I <totalnum; I ++ ) { 結果 = +結果i.ToStringを(); } // タイムコードセグメントカウントする必要 st.Stopを(); // 終了タイミング Console.WriteLineを(文字列 .Format(「仕上げ+総時間接続文字列{0}ミリ秒!」、 st.ElapsedMilliseconds.ToString())); } /// <まとめ> /// スプライシング列sによって /// </要約> /// <名前= PARAM "totalnum"> </ param>の プライベート 静的 無効 StringBuilderString(int型 totalnum) { /// /ストップウォッチ、アクセスの実行時間の実装定義 ザ・ストップウオッチST = 新しい新しいザ・ストップウオッチ(); // インスタンス化クラス st.Start(); // 開始タイミング Console.WriteLineをする(「StringBuilderの間を接続文字列を開始しました:」); StringBuilderの結果 = 新しい新規のStringBuilder(); /// /アレイを定義 するために(INT I = 0 I <totalnum; I ++ ) { result.append(i.ToString()); } 文字列結果2 = result.ToString( ); //時間カウントするためのコードセグメントの必要性 st.Stopを(); // 終了時期 Console.WriteLineを(文字列 .Format(" !接続文字列{0}ミリ秒を通じて完成、StringBuilderの合計時間" 、 St.ElapsedMilliseconds.ToString() )); } /// <まとめ> /// スプライシングStringBuilderの文字列であることを指定し長初期 /// </要約> /// <PARAM NAME = "totalnum"> </ PARAM> プライベート 静的 ボイド StringBuilderString2 (int型totalnum) { /// /ストップウォッチは、アクセスの実行時間の実装定義 ストップウオッチST = 新しい新しいストップウォッチを(); //インスタンス化クラス st.Start(); // 開始時期 (Console.WriteLineをする"StringBuilderの間を接続文字列を開始しました:" ); StringBuilderの結果 = 新しい新しいのStringBuilder(totalnum * 6。); /// /アレイの定義 について(をint型私は= 0 ; I <totalnum; I ++ ) { result.append(i.ToString()); } 文字列結果2 = result.ToString(); // ニーズがタイムコードセグメントカウントする st.Stopを(); // 終了タイミング Console.WriteLineを(文字列 .Format(" 接続文字列を経て完成し、StringBuilderの合計時間{0}ミリ秒!" 、 St.ElapsedMilliseconds.ToString())); } } }
結果を分析し、まとめたもの:
2つの点をテストします。
+とOHのStringBuilder文字列連結のパフォーマンスを比較することによって:一つの試験があります
第二の試験は、次のとおり性能比較のStringBuilderは、長さと初期の長さを初期化しません
おそらく、以下の結論を引き出します
図1に示すように、文字列少ないスプライスされる、+と有意なパフォーマンスの差のStringBuilder
2、長い文字列のステッチ、StringBuilderの利点より多くの明白な
図3は、初期の推定長さよりも同じ文字列のStringBuilderスプライシング効率は、指定された長さを初期化するためには効率的ではありません
これを言って、私たちは、すべての使用方法を理解していると信じています。まあ、時間が遅れている、とすぐに睡眠を洗う、明日は仕事に行かなければなりませんか?
終わり