StringBuiilder を利用して複数の文字列を結合するコードと実行結果を紹介します。
C#で文字列を結合する場合はこちらの記事で紹介している"+"演算子を利用する処理が一般的です。しかし、タイ利用の文字列を連結して文字列が非常に長くなる場合 "+"演算子を利用した処理では動作速度が低下することがあります。この記事ではStringBUidlerを利用して文字列を高速に結合するコードを紹介します。
文字列の結合にはStringBuiilderクラスのAppend() メソッドを利用します。
Windowsフォームアプリケーションを作成し、下図のUIを作成します。ボタンとMultilineプロパティをTrueに設定した複数行のテキストボックスを配置します。
下記のコードを記述します。ボタンのClickイベントを実装しています。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace StringConcatenation
{
public partial class FormStringBuilder : Form
{
public FormStringBuilder()
{
InitializeComponent();
}
private void Button1_Click(object sender, EventArgs e)
{
string[] text = new string[8];
text[0] = "ぺんぎんクッキー";
text[1] = "らくだキャラメル";
text[2] = "くじらケーキ";
text[3] = "しろくまアイス";
text[4] = "かるがもサブレ";
text[5] = "たぬきチョコレート";
text[6] = "かもしかビスケット";
text[7] = "あひるタルト";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < text.Length; i++) {
sb.Append(text[i]);
}
string result = sb.ToString();
textBox1.Text = result;
}
}
}
ボタンをクリックすると、初めに元データの文字列を作成します。今回はstring型の配列で作成しています。8つの要素を作成し文字列を代入して設定しています。
string[] text = new string[8];
text[0] = "ぺんぎんクッキー";
text[1] = "らくだキャラメル";
text[2] = "くじらケーキ";
text[3] = "しろくまアイス";
text[4] = "かるがもサブレ";
text[5] = "たぬきチョコレート";
text[6] = "かもしかビスケット";
text[7] = "あひるタルト";
StringBuilderオブジェクトを作成し、forループで配列の要素を一つずつStringBuilderにAppendメソッドを呼び出して追加します。Appendメソッドの引数にはStringBulderの末尾に追加する文字列を与えます。今回のコードは、先頭の配列から順番にStringBuilderの末尾に文字列を追加する動作になります。
StringBuilder sb = new StringBuilder();
for (int i = 0; i < text.Length; i++) {
sb.Append(text[i]);
}
テキストボックスに文字列を表示するためStringBuilderオブジェクトを文字列に変換します。文字列への変換はStringBuilderクラスのToString() メソッドを呼び出して変換します。
string result = sb.ToString();
textBox1.Text = result;
上記のプロジェクトを実行します。下図のウィンドウが表示されます。
[button1]をクリックします。テキストボックスに下図の文字列が表示されます。data配列に代入した文字列が連結された文字列がテキストボックスに表示できていることが確認できます。
StringBuilderを利用して文字列の連結ができました。
実際に"+"演算子を用いた場合と比較してどの程度高速に動作するか速度を比較します。
下図のUIを作成します。Windowsフォームアプリケーションを作成し、ボタンとMultilineプロパティをTrueに設定した複数行のテキストボックスを配置します。
下記のコードを記述します。System.Web.Security 名前空間のオブジェクトを利用するため、プロジェクトの参照に "System.Web" アセンブリを追加する必要があります。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace StringConcatenation
{
public partial class FormStringBuilderCompair : Form
{
public FormStringBuilderCompair()
{
InitializeComponent();
}
private void Button1_Click(object sender, EventArgs e)
{
string[] data = new string[32768];
for (int i = 0; i < data.Length; i++) {
data[i] = System.Web.Security.Membership.GeneratePassword(32, 0);
}
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
textBox1.Text += "処理の開始 +の連結\r\n";
sw.Start();
string result1 = "";
for (int i = 0; i < data.Length; i++) {
result1 = result1 + data[i];
}
textBox1.Text += "処理の完了 : " + sw.ElapsedMilliseconds;
sw.Stop();
textBox1.Text += "\r\n----\r\n";
//
sw.Reset();
//
textBox1.Text += "処理の開始 StringBuilderの連結\r\n";
sw.Start();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < data.Length; i++) {
sb.Append(data[i]);
}
string result2 = sb.ToString();
textBox1.Text += "処理の完了 : " + sw.ElapsedMilliseconds;
sw.Stop();
textBox1.Text += "\r\n----\r\n";
}
}
}
ボタンがクリックされると、下記のコードで文字列を生成します。今回は32文字のランダムな文字列を32768個生成します。
string[] data = new string[32768];
for (int i = 0; i < data.Length; i++) {
data[i] = System.Web.Security.Membership.GeneratePassword(32, 0);
}
Stopwatchオブジェクトを作成し処理にかかった時間を計測します。処理の開始メッセージを表示後Stopwatchを開始します。forループでランダムに作成した文字列配列を"+"演算子を利用して順番に結果文字列の末尾に結合します。処理が終わったら、Stopwatchの時間を表示します。
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
textBox1.Text += "処理の開始 +の連結\r\n";
sw.Start();
string result1 = "";
for (int i = 0; i < data.Length; i++) {
result1 = result1 + data[i];
}
textBox1.Text += "処理の完了 : " + sw.ElapsedMilliseconds;
sw.Stop();
Stopwatchオブジェクトをリセットしカウントを0に戻します。処理の開始のメッセージ表示後Stopwatchオブジェクトを開始します。forループでランダムに作成した文字列の配列をStringBuilderオブジェクトに追加します。追加後stringオブジェクトにToString()メソッドを呼び出して変換します。処理の完了メッセージ表示時にStopwatchオブジェクトの時間を表示します。
sw.Reset();
textBox1.Text += "処理の開始 StringBuilderの連結\r\n";
sw.Start();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < data.Length; i++) {
sb.Append(data[i]);
}
string result2 = sb.ToString();
textBox1.Text += "処理の完了 : " + sw.ElapsedMilliseconds;
sw.Stop();
プロジェクトを実行します。下図のウィンドウが表示されます。
[button1]をクリックします。処理が実行され、しばらくするとテキストボックスに下図の結果が表示されます。
"+" で連結した場合の処理時間は、16.5秒ほどかかっていますが、StringBuilderで連結した場合は、0.001秒(1ミリ秒)で処理が完了していることがわかります。多くの文字列を連結する場合はStringBuilderを利用したほうが高速に処理できます。