【行いたいこと】
既存の処理(文字列の配列から1つデータを取り出して○○する*1処理6秒位です)
を並列で処理して時間の短縮を図りたいと考えています。
配列から1つデータを取り出す際には排他処理を行って取り出すデータにダブりが無いようにしたいです。
*因みにこの配列自体が20万近くデータがありますのでそこそこ長い時間処理を続けることになります
【行ったこと】
・並列処理はtaskを使用すれば良いということでTask.Factory.StartNewで取り敢えず10個タスクを作って実行
・排他処理はMutexを使用して多重起動を禁止すれば良いということで配列のカウントアップする処理をMutexのWaitOneで排他処理にした
【疑問】
Testで配列から取り出した文字列をConsole.Writeで書き出すテストを「taskを使用しない方法」と「10個taskを作って並列で処理する方法」で試した結果、何故か後者の方が遅い結果となりました。
何故並列処理を行って遅い結果となるのか原因が知りたいです。
*ThreadIDを出して確認しましたが、複数のtaskは走っているようです。そうなるとMutexの使い方が間違っているのかなと考えたのですが、行き詰まってしまったので質問させて頂きました。宜しくお願いいたします。
【コード】
//文字列の配列クラス
class StringArray
{
private string[] arystring;
private string strTemporary;
private int intI;
private Mutex objMutex = new Mutex();
public StringArray(string[] aarystring) { this.arystring = aarystring; intI = 0; } //呼び出されると文字列データを返す() public string GetString() { //配列の限界に達したら空文字を返す if (intI >= this.arystring.Length) { return "空文字__" + intI; } //配列のカウントアップの重複を避けたいのでここから多重起動を禁止する objMutex.WaitOne(); strTemporary = this.arystring[intI]; intI = intI + 1; objMutex.ReleaseMutex(); return strTemporary + "__" + intI.ToString(); }
}
private void button3_Click(object sender, EventArgs e)
{
int intI;
int intJ;
int intK;
//何らかの文字列配列を用意*今回は0~2000までの数字を文字列として渡すことにします string[] arystring; ArrayList aryTemporary = new ArrayList(); for (intI = 0; intI < 2000; intI++) { aryTemporary.Add(intI.ToString()); } arystring = (string[])aryTemporary.ToArray(typeof(string)); //文字列配列のクラスを定義する StringArray classStringArray = new StringArray(arystring); //【比較テスト】 //○並列処理ではない場合 /* var watch0 = Stopwatch.StartNew(); for (intJ = 0; intJ < arystring.Length; intJ++) { Console.Write("0__結果:{0}__経過時間:{1}" + Environment.NewLine, classStringArray.GetString(), watch0.ElapsedMilliseconds); } */ //○並列処理の場合 var watch = Stopwatch.StartNew(); for (intK = 0; intK < 10; intK++) { Task.Factory.StartNew(() => { for (intJ = 0; intJ < arystring.Length; intJ++) { Console.Write("1__実行数:{0}__経過時間:{1}" + Environment.NewLine, classStringArray.GetString(), watch.ElapsedMilliseconds); } }); } return;
}
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。