#概要
色々な高速化などの噂について検証してみました
探せばいくらでもあるforとforeachの速度などは載せていません
##なるべく二進数換算で小さい値に
2進数換算をした時に、1の数がなるべく少ない方が高速らしいという噂を聞いてやってみた
###結果
+n | 二進数換算 | 結果 | +m%(+2基準) |
---|---|---|---|
+2 | 10 | 138459ms | 0% |
+127 | 1111111 | 148959ms | +7% |
+128 | 10000000 | 139022ms | +0.4% |
###コード
var sw = new System.Diagnostics.Stopwatch();
//-----------------
// 計測開始
sw.Start();
// ★処理A
for(int i = 0; i < 100000000; i++) {
int num = 0;
for(int j = 0; j < 1000; j++) {
num += 2;
}
}
// 計測停止
sw.Stop();
// 結果表示
Console.WriteLine("■処理Aにかかった時間");
Console.WriteLine($" {sw.ElapsedMilliseconds}ミリ秒");
sw.Reset();
sw.Start();
// ★処理B
for (int i = 0; i < 100000000; i++) {
int num = 0;
for (int j = 0; j < 1000; j++) {
num += 127;
}
}
// 計測停止
sw.Stop();
// 結果表示
Console.WriteLine("■処理Bにかかった時間");
Console.WriteLine($" {sw.ElapsedMilliseconds}ミリ秒");
sw.Reset();
sw.Start();
// ★処理C
for (int i = 0; i < 100000000; i++) {
int num = 0;
for (int j = 0; j < 1000; j++) {
num += 128;
}
}
// 計測停止
sw.Stop();
// 結果表示
Console.WriteLine("■処理Cにかかった時間");
Console.WriteLine($" {sw.ElapsedMilliseconds}ミリ秒");
System.Threading.Thread.Sleep(10000);
}
###補足
1000回の足し算を1億回やってこの程度(+7%)なのであまり気にしなくていいかもしれない
あと1000回の足し算を1000回程度ならPCの調子か、+128の方が遅いという結果になることも多少あったので、気休め程度に。
##ビットシフトを使う
2の乗数で割り算をするとき、ビットシフトを使うと高速らしいという話を検証
###結果
やり方 | 結果 | +n%(/=基準) |
---|---|---|
/= | 20798ms | 0% |
= num/2 | 20660ms | -1% |
num>>=1 | 4429ms | -79% |
コード
for(int i = 0; i < 10000000; i++) {
int num = int.MaxValue;
while(num > 2) {
num /= 2; //この部分を変更
}
}
###補足
処理時間が5分の1……!
/=2とnum=num/2の差については誤差らしいというのを次項で説明
##num/=2とnum=num/2
VisualStudioでは逆アセンブリという機能があり、それでデコンパイル状態のコード(アセンブリ言語?)を見ることができる
そこで見てみると、同じらしい
num /= 2;
mov eax,dword ptr [ebp-44h]
mov ecx,2
cdq
idiv eax,ecx
mov dword ptr [ebp-44h],eax
num2 = num2 / 2;
mov eax,dword ptr [ebp-48h]
mov ecx,2
cdq
idiv eax,ecx
mov dword ptr [ebp-48h],eax
全く同じ処理をしているので、全く同じ速度ということになるはずということで、誤差ということが判明
##構造体とクラス
構造体の方が早いらしい。ただし一定以上のバイト数になるとクラスの方がいいらしい
###結果
バイト数 | 構造体 | クラス | 処理時間(構造体を100%としたとき) |
---|---|---|---|
4 | 1731ms | 5407ms | 312% |
16 | 1725ms | 5916ms | 342% |
20 | 1808ms | 6341ms | 350% |
32 | 1898ms | 7399ms | 390% |
40 | 2076ms | 7178ms | 345% |
44 | 9946ms | 8416ms | 85% |
60 | 10366ms | 8296ms | 80% |
64 | 8557ms | 9155ms | 107% |
104 | 11142ms | 10512ms | 94% |
128 | 8568ms | 12236ms | 143% |
###補足
構造体だと2の乗数で処理速度が上がるらしい
場合と数が大きいほどclassを使うメリットがあり、ぎりぎりまで高速化したい場合はstructか
ただ、さまざまなところで見た16bitが境目という話はなかったし、40~44の間で劇的に構造体が遅くなる理由は見当もつかないので、この話題について掘り下げるのは避けたいと思う
##その他メモ
・stringは極力StringBuilderを使った方が早い
・ifとswitchはifの方が基本早い
・多分岐では上から順に出現頻度が多い条件を書くことで比較回数を減らすことができる
#Unity編
・UnityのgameObject.tag=="hoge"より、gameObject.CompareTag("hoge")の方が早いらしい。gameObject.tagのアクセスが処理を食うとか
・UI周りの最適化など
・Resourcesは出来る限り使わない
・全般のパフォーマンス改善