Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9541

【C#】ループステートメントの速度を検証してみた

$
0
0

最近、C#でWindowsフォームアプリケーションを作成することが増えました。ループステートメントは基本的には適材適所の使い分けかと思いますが、私は主にforeach文を使用していました(書き方がシンプルで好きです)。ループステートメントは色々書き方あるものの速度は実際どうなのかなと気になったので、検証結果をまとめてみました。

ループステートメントの種類

for

for(初期化式;条件式;更新式){反復処理;}

foreach

foreach(変数名in配列){反復処理;}

while

while(条件式){反復処理;}

do-while

do{反復処理;}while(条件式);

LINQ

書き方はソースで確認

検証ソース

1億個の要素を持った配列の総和を求める関数を100回実施した平均値を計測する。

usingSystem;usingSystem.Linq;namespaceVerify{classProgram{privatestaticDateTimestart;privatestaticDateTimeend;privatestaticreadonlyintlistCnt=100000000;privatestaticreadonlyintloopCnt=100;privatestaticreadonlyStringresultFormat="{0:0.0 ms}";/// <summary>/// 検証/// </summary>/// <param name="args"></param>staticvoidMain(string[]args){LoopVerify();}/// <summary>/// ループ系関数の速度検証///  1. for文///  2. foreach文///  3. while文///  4. do-while文///  5. LINQ文///  6. LINQ文(パターン2)/// 予め用意した配列の要素トータルを計算する速度を検証する。/// </summary>privatestaticvoidLoopVerify(){double[]doForVerifyList=newdouble[loopCnt];double[]doForEachVerifyList=newdouble[loopCnt];double[]doWhileVerifyList=newdouble[loopCnt];double[]doDoWhileVerifyList=newdouble[loopCnt];double[]doLINQQueryVerifyList=newdouble[loopCnt];double[]doLINQMethodVerifyList=newdouble[loopCnt];int[]verifyList=Enumerable.Repeat<int>(1,listCnt).ToArray();for(inti=0;i<loopCnt;i++){doForVerifyList[i]=DoForVerify(verifyList);doForEachVerifyList[i]=DoForEachVerify(verifyList);doWhileVerifyList[i]=DoWhileVerify(verifyList);doDoWhileVerifyList[i]=DoDoWhileVerify(verifyList);doLINQQueryVerifyList[i]=DoLINQQueryVerify(verifyList);doLINQMethodVerifyList[i]=DoLINQMethodVerify(verifyList);}// それぞれの平均値を出力Console.WriteLine("ForAvg:"+String.Format(resultFormat,doForVerifyList.Average()));Console.WriteLine("ForEachAvg:"+String.Format(resultFormat,doForEachVerifyList.Average()));Console.WriteLine("WhileAvg:"+String.Format(resultFormat,doWhileVerifyList.Average()));Console.WriteLine("DoWhileAvg:"+String.Format(resultFormat,doDoWhileVerifyList.Average()));Console.WriteLine("LINQQueryAvg:"+String.Format(resultFormat,doLINQQueryVerifyList.Average()));Console.WriteLine("LINQMethodAvg:"+String.Format(resultFormat,doLINQMethodVerifyList.Average()));}/// <summary>/// forの検証/// </summary>/// <param name="_verifyList">検証配列</param>/// <returns>経過時間(ミリ秒)</returns>privatestaticdoubleDoForVerify(int[]_verifyList){inttotal=0;start=DateTime.Now;for(inti=0;i<=_verifyList.Length-1;i++){total+=_verifyList[i];}end=DateTime.Now;return(end-start).TotalMilliseconds;}/// <summary>/// foreachの検証/// </summary>/// <param name="_verifyList">検証配列</param>/// <returns>経過時間(ミリ秒)</returns>privatestaticdoubleDoForEachVerify(int[]_verifyList){inttotal=0;start=DateTime.Now;foreach(intiin_verifyList){total+=i;}end=DateTime.Now;return(end-start).TotalMilliseconds;}/// <summary>/// whileの検証/// </summary>/// <param name="_verifyList">検証配列</param>/// <returns>経過時間(ミリ秒)</returns>privatestaticdoubleDoWhileVerify(int[]_verifyList){inttotal=0;inti=0;start=DateTime.Now;while(i<=_verifyList.Length-1){total+=_verifyList[i];i++;}end=DateTime.Now;return(end-start).TotalMilliseconds;}/// <summary>/// do-whileの検証/// </summary>/// <param name="_verifyList">検証配列</param>/// <returns>経過時間(ミリ秒)</returns>privatestaticdoubleDoDoWhileVerify(int[]_verifyList){inttotal=0;inti=0;start=DateTime.Now;do{total+=_verifyList[i];i++;}while(i<=_verifyList.Length-1);end=DateTime.Now;return(end-start).TotalMilliseconds;}/// <summary>/// LINQの検証(クエリ構文)/// </summary>/// <param name="_verifyList">検証配列</param>/// <returns>経過時間(ミリ秒)</returns>privatestaticdoubleDoLINQQueryVerify(int[]_verifyList){start=DateTime.Now;inttotal=(fromxin_verifyListselectx).Sum();end=DateTime.Now;return(end-start).TotalMilliseconds;}/// <summary>/// LINQの検証(メソッド構文)/// </summary>/// <param name="_verifyList">検証配列</param>/// <returns>経過時間(ミリ秒)</returns>privatestaticdoubleDoLINQMethodVerify(int[]_verifyList){start=DateTime.Now;inttotal=_verifyList.Sum(x=>x);end=DateTime.Now;return(end-start).TotalMilliseconds;}}}

実行結果

1回目

ForAvg:387.8 ms
ForEachAvg:419.6 ms
WhileAvg:391.0 ms
DoWhileAvg:391.2 ms
LINQQueryAvg:1236.2 ms
LINQMethodAvg:1216.8 ms

2回目

ForAvg:375.6 ms
ForEachAvg:408.2 ms
WhileAvg:377.1 ms
DoWhileAvg:366.7 ms
LINQQueryAvg:1188.7 ms
LINQMethodAvg:1176.5 ms

3回目

ForAvg:354.1 ms
ForEachAvg:379.8 ms
WhileAvg:358.9 ms
DoWhileAvg:355.1 ms
LINQQueryAvg:1135.5 ms
LINQMethodAvg:1124.3 ms

結論

for文が1番早かったです。LINQは抜きにしても、foreachが一番遅かったのは少々ショックな結果となりました。
今回、反復処理の中で特に条件分岐等がなかったためLINQには不利な検証条件だったかと思います。
そのため、もう一度それらを踏まえた検証を行いたいと思います。次回に乞うご期待を。


Viewing all articles
Browse latest Browse all 9541

Trending Articles