今日のC#インタラクティブ (2018/02/10) 速度比較! MOD 演算 vs. AND 演算編

こんにちは、Takymです。
お久しぶりのC#インタラクティブのお時間です。
今回はベンチマークをして遊びたいなと思います。
因みに、今回は今日のC#インタラクティブ (2017/06/08) ~ベンチマークプログラム編~csi.exeの方が早かったのでそちらの方を使います。


前置きを飛ばして本編を見たい方はこちらをクリックしてください。
結果だけを見たい方はこちらをクリックしてください。

比較対象のプログラム

今回、検証することは剰余演算偶数奇数判定AND演算偶数奇数判定でどちらの方が早いのかです。
以下のようにすれば偶数か奇数かを判定できるのですが、僕はAND演算の方が早そうだと思い今回の検証をしようと思いました。

int i = ???;
// MOD演算法
if ((i % 2) == 0) return "偶数";
if ((i % 2) != 1) return "偶数";
if ((i % 2) == 1) return "奇数";
if ((i % 2) != 0) return "奇数";
// AND演算法
if ((i & 1) == 0) return "偶数";
if ((i & 1) != 1) return "偶数";
if ((i & 1) == 1) return "奇数";
if ((i & 1) != 0) return "奇数";

どうやって検証するのかと言うと、この偶数奇数判定プログラムを数十万回程度実行させてその差を求めて早い方を勝ちとします。

(int evens, int odds) DoModOperation()
{
int evens = 0, odds = 0;
for (int i = 0; i < 100000; ++i) {
if ((i % 2) == 0) {
++evens;
} else if ((i % 2) == 1) {
++odds;
}
}
for (int i = 0; i < 100000; ++i) {
if ((i % 2) != 1) {
++evens;
} else if ((i % 2) != 0) {
++odds;
}
}
return (evens, odds);
}
(int evens, int odds) DoAndOperation()
{
int evens = 0, odds = 0;
for (int i = 0; i < 100000; ++i) {
if ((i & 1) == 0) {
++evens;
} else if ((i & 1) == 1) {
++odds;
}
}
for (int i = 0; i < 100000; ++i) {
if ((i & 1) != 1) {
++evens;
} else if ((i & 1) != 0) {
++odds;
}
}
return (evens, odds);
}

このプログラムでは最初に紹介した全ての演算法を使っています。
あと、戻り値がタプル型の値にしているのは、偶数と奇数の数がMOD演算とAND演算で同じかどうか判定する為に一応つけておきました。

実行環境

以下の様な環境でベンチマークをしました。

種類 バージョン
OS Microsoft Windows 10 Fall Creators Update (CodeName: Redstone 3, Version: 1709, OS Build: 16299.192, 64ビット)
CPU Inter(R) Core(TM) i5-4210U CPU @ 1.70GHz 2.40GHz (x86-64)
メモリ 8GB
Microsoft Visual Studio 2017 v15.5.5
.NET Framework v4.7.02556
Microsoft (R) Visual C# インタラクティブ コンパイラ v2.6.0.62329

いざ実行!

以下の様なプログラムをcmd.exeに入れて実行してみます。
C#インタラクティブ用の記述になっています。

// (※DoModOperationとDoModOperationは省略)
(int evensM, int oddsM) = DoModOperation();
(int evensA, int oddsA) = DoAndOperation();
evensM == evensA && oddsM == oddsA
int scoreM = 0, scoreA = 0;
for (int x = 0; x  timeA) {
++scoreM;
} else if (timeM  scoreA) {
WriteLine("MOD演算の勝ち! AND演算の負け...");
} else if (scoreM < scoreA) {
WriteLine("AND演算の勝ち! MOD演算の負け...");
} else {
WriteLine("引き分け!?");
}

scoreMはMOD演算が速かった回数、scoreAはAND演算が速かった回数を表します。

.
.
.
.
.
..
..
..
..



….
….
…..
実行
結果

evensM == evensA && oddsM == oddsAの結果はtrueでした。
自分のプログラムが正しく動作してくれていて嬉しいです。
それで、AND演算勝ちました。
以下が証拠写真です。

scoreMとscoreAの合計が20にならないのは、15回引き分けになったとういう事ですね。
しかし、もう一度実行したら、今度はMOD演算勝ちました。
しかもscoreMの値は4でした。

つまり、結果は運による様ですね。つまりどっちも同じくらいの速度のようです。
でもscoreMとscoreAを見比べてみると、MOD演算の方が微妙に早そうです。予想が外れてビックリです。

感想

二種類の比較方法はあまり速度に違いが無いようなので、僕はこれからはAND演算を使おうと思います。
なぜAND演算なのかと言うと、ただの趣味です。なんか&記号が恰好いいし・・・
何かC#インタラクティブで検証して欲しい物等あればコメントしてください。
感想・意見・質問・誤字・脱字等はこの記事のコメント欄にお願いします。
最後まで読んでくださってありがとうございました。

コメントを残す

WordPress.com で次のようなサイトをデザイン
始めてみよう