速度比較をしたい!
UnityでC#のコードの最適化をしていて、「この書き方とこの書き方ではどっちが速いんや!」ってなることがよくあるので、速度比較をする時のベストプラクティスを模索してみました。
その1,検証用のコードはTest Runnerで書く
ちょっとテストコードを書きたいときに、空のゲームオブジェクト作ってスクリプトをアタッチして終わったら消すのって地味にめんどくさいです。
Test Runnerを使えば、上記の手順を踏むことなくコードを書いてすぐに実行できるので、爆速でトライ&エラーが出来ます。
詳しい使い方はこちらの記事が分かりやすかったです↓
Unity使いは全員Unity Test Runnerを使え!爆速のトライ&エラー環境だぞ!
その2,時間を計るだけならStopwatchクラス
時間を計りたいだけならStopwatchクラスが簡単で便利そうです。
現実のストップウォッチのような使い方で時間を計ることが出来ます。
参考↓
より高い精度で時間を計測する
その3,時間とGC Allocも図りたければPlofiler
時間やらGC Allowやらその他諸々を計測したい場合は、UnityのPlofilerを使いましょう。
速度比較に限らず、最適化には必須の機能なので絶対に使い方を覚えておいた方がいいです。
詳しい使い方はこちらの記事が分かりやすかったです↓
【Unity】CPUプロファイラでパフォーマンスを改善する 前編
その4,ILを確認する(上級者向け)
C#で書いたコードはコンパイルした際にILというものに変換され、そこから更に機械語に変換されて実行されます。
この変換の際にコンパイラがコードを良い感じに最適化してくれるので、実はC#のコードだけを見ても実際にどういう処理が行われるのかはよく分かりません。
例えば、変数の宣言をループ外に書くか、ループ内に書くかの違いがある以下の2つのコードですが、ILを確認してみると全く同一の処理であることが分かります。
public class C {
public void M() {
int sum = 0;
int count = 0;
int num;
while(count < 100){
count++;
num = count;
sum += num;
}
}
}
public class C {
public void M() {
int sum = 0;
int count = 0;
while(count < 100){
count++;
int num = count;
sum += num;
}
}
}
ILの確認にはSharpLabというWebサービスが便利です。試しに上のコードをコピペしてみましょう。
しかしSharpLabでは、標準ライブラリしか使えないようなのでUnity固有のライブラリを使う場合は、スクリプトをdll化し、逆アセンブルする必要がありそうです。
やり方はこちらの記事が分かりやすかったです↓
UnityのスクリプトをDLL化する
C#で作られたプログラムをデコンパイルしてみよう
ILを確認することで、そのコードが速度比較に適したものかどうかを確認したり、なぜその計測結果になるのかを調べる助けになると思います。
まとめ
正確な速度比較をしようと思うとかなり高度な知識が必要になってしまいますが(ILとか機械語とかワカラン)、Stopwatchで時間を計るコードを書いてTest Runnerで実行するくらいなら簡単にできそうですね。
ご意見ご感想、それは違うよ!等ございましたらコメントを頂けますと幸いです。