- - PR -
StringBuilderの使い方について。
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2003-11-08 13:05
ご教示願います。
文字列連結において、StringBuilderを使用した方が高速である… と説明されています。 うまく説明出来ないのですが、以下の様なコードの場合、 Dim sb As New StringBuilder Dim st As String For i = 0 To 10000 For x = 0 To 2000 sb.Append("TESTTEST") Next st = sb.ToString() Next 上記でst = sb.ToString()の後、 sbを初期化したい場合、 自分は、sb.Replace(sb.ToString(), Nothing)と書いてますが 一般的には他にどの様な方法があるのでしょうか? データベースから拾ってきたデータをループして加工する際、 文字列連結でこのStringBuilderが使えるな、と思ったのですが、 初期化方法がよく分からなくて…単純にループ内冒頭で StringBuilderを定義するのがイイのでしょうか…? 分かりにくい文章で申し訳ありませんが、どなたかご指導お願いします。 | ||||
|
投稿日時: 2003-11-08 13:14
sb.Length = 0
とか、どうでしょうか? | ||||
|
投稿日時: 2003-11-08 13:36
mei様、ご回答ありがとうございます。
sb.Length = 0 にすると、このインスタンスの長さが0になり、 sb.Remove(0, sb.Length) にすると、 現在のインスタンスの文字列値が length だけ短縮されます。容量には影響ありません。 との事です。 すみません、根本的な事が理解出来ていないのですが、 ループ処理等で使うにはどちらがベターなのでしょうか? | ||||
|
投稿日時: 2003-11-08 14:53
> sbを初期化したい場合、
> 自分は、sb.Replace(sb.ToString(), Nothing)と書いてますが > 一般的には他にどの様な方法があるのでしょうか? 僕の場合、普通に、 [C#] sb = new StringBuilder(); と初期化します。 メモリが気になるのであれば、参照カウンタを減らし(Nothing を代入し)て、 GC.Collect(); します。 | ||||
|
投稿日時: 2003-11-09 00:12
速度の面から見た場合、オブジェクトのnewを頻繁に行うのは好ましくありません。 それと、メモリのアロケートもコストがかかります。 なので、作業用のStringBuilderをループの外で作成するのが良いと思います。 あと、文字列の最大長が分かっている場合は、 StringBuilderのキャパシティも指定した方が良いかも知れません。 # 文字列の長さのばらつきが極端にあったりすると話は変わってきますが・・・ ・初期化方法 パフォーマンスを測ってないので何ともいえませんが、 Length = 0だと、恐らく内部の長さ管理変数を0にするだけだと思うので、 処理が軽いと予想します。 ・おまけ str = GetStr1() + GetStr2() + GetStr3() + ...; ↑こういう場合は、StringBuilderよりも上記のように羅列した方が速いです。 #ちょっと意外で驚きました・・・ | ||||
|
投稿日時: 2003-11-09 15:01
長さ(Length プロパティ)と容量(Capacity プロパティ)は別物です。StringBuilder ではあらかじめある程度の領域を確保しておき(「あらかじめ」というのは語弊があるかもしれませんが)、その領域に文字列を保存します。Capacity プロパティはその領域の大きさ(容量)を表します。Length プロパティは保存している文字列の実際の長さです。
| ||||
|
投稿日時: 2003-11-09 17:52
dai様、mei様、IZUMI様ご回答有難うございます。
そうですね…やはり作業用のStringBuilderは、ループの外で 作成しようと思います。 肝心の初期化方法については、RemoveとLengthとで簡単なサンプルを 作成してテストしてみるのが一番ですね…。 ただ対象がASP.NETなので、まずはWindows Formでテストしてみます。 あとIZUMI様のお話ですと、やはりRemoveよりもLength = 0と記述した 方が効率的という事でしょうか? | ||||
|
投稿日時: 2003-11-09 22:50
自宅PC(OS:Windows2000 SP4)にVS.NET2002が入っていたのを
思い出しまして、簡単なコンソールアプリでテストしてみました。 ↓ sTime = Now Dim x As Int32 Dim y As Int32 Dim sb1 As New StringBuilder() Dim st1 As String For x = 0 To 5000 For y = 0 To 5000 sb1.Append("Test") Next st1 = sb1.ToString() sb1.Length = 0 Next eTime = Now Console.WriteLine("String Builder No1 " & eTime.Subtract(sTime).TotalSeconds & " seconds.") sTime = Now Dim xx As Int32 Dim yy As Int32 Dim sb2 As New StringBuilder() Dim st2 As String For xx = 0 To 5000 For yy = 0 To 5000 sb2.Append("Test") Next st2 = sb2.ToString() sb2.Remove(0, sb2.Length) Next eTime = Now Console.WriteLine("String Builder No2 " & eTime.Subtract(sTime).TotalSeconds & " seconds.") sTime = Now Dim xxx As Int32 Dim yyy As Int32 Dim sb3 As New StringBuilder() Dim st3 As String For xxx = 0 To 5000 For yyy = 0 To 5000 sb3.Append("Test") Next st3 = sb3.ToString() sb3.Replace(sb3.ToString(), Nothing) Next eTime = Now Console.WriteLine("String Builder No3 " & eTime.Subtract(sTime).TotalSeconds & " seconds.") ↑ 結果ですが、 No1 (Length = 0)が、8.4421392 seconds. No2 (Remove)が、8.2017396 seconds. No3 (Replace)が、9.113104 seconds. という結果でした。 何度か実行してみましたが、No2 , No1 , No3 という順序は 変更ありませんでした。 |