LoginSignup
25
28

More than 5 years have passed since last update.

Unity C# パフォーマンス向上(foreach編)

Last updated at Posted at 2017-06-21

前振り

iPhone5SAndroid4.4, 5などで発売された端末でやけにもっさりして、
パフォーマンスの見直しが必要だと思った方に見てもらいたい内容です。
 
 

そして、今回のテーマは「的確なLoop処理の対応について」です。
 
 


環境

 
Unity 5.5以降 5.6未満

loop処理の改善

【それぞれのloop処理について】

  1. 型[] array = new 型();
  2. List<型> list = new List<型>();
  3. Dictionary<型, 型> dic = new Dictionary<型, 型>();
  4. IEnumerator enu;  

【対応方法】

 
上記の4つのloop処理は、以下のような対応が必要となります。

1.arrayの対応

for(int i = 0; i < array.Length; i++) {
  var data = array[i];
}

 
2.listの対応

for(int i = 0; i < list.Count(); i++) {
  var data = list[i];
}

 
3.dicの対応

foreach(var value in dic.Keys) {
 // keyが欲しいとき
}

foreach(var value in dic.Values) {
 // valueが欲しいとき
}

 
4.enuの対応

var list = enu.GetEnumerator();
try {
  while(list.MoveNext()) {

    var data = list.Current;

  }
}
finally {
  list.Dispose();
}

 

【解説】

4の対応についてですが、一般的には、foreachでloop処理して中身を取り出すことが多いです。

C#の解説でもよく見かけますし、特に変わりはないとされていましたが、Unity C#となると話は別です。
 

using展開のコンパイラバグ

「Listをforeachで回すとGCゴミが出るのはUnityのコンパイラが古いせいでバグッてるから」というのが良く知られている話ですが、
より正しい理解に変えると、「構造体のIDisposableに対するusingの展開結果が最適化されていない(仕様に基づいていない)」ということになります。
この辺の話はECMA-334 C# Language Specificationにも乗っているので、C#コンパイラの仕様に対するバグと言えるのではないか。

※参考記事に書かれている内容です。
 

【参考記事】

C#のGCゴミとUnity(5.5)のコンパイラアップデートによるListのforeach問題解決について
http://neue.cc/2016/08/05_537.html

C# Dictionary のループのパフォーマンス
https://www.dcom-web.co.jp/lab/cs/dictionary-loop
 

 

 

おまけ

ちなみにforeachの対応前と対応後になります。
そんなに変わりませんが、対応前よりもCPU Usageで60FPSをギリギリ超えなくなっていますね。
 
↓foreach対応前
foreach対応前.png

 

↓foreach対応後
foreach対応後.png

 

 

おまけ2

テラシュールブログの山村さんの記事で、以下の対応策が挙げられていました。
 
・localPositionを使う
・Vectorのoperationを減らす
・VectorのMathfを使用しない
・transformのキャッシュ
・エンジンコードの呼び出し削減
・time.deletaTimeの削減
・foreachを使用しない ← 今回のお話し
・一覧でアクセスするなら、Listではなく、Arrayを使用する
・NonAllocと名のつくAPIを使う(RaycastNonAlloc等)
・stringの結合は避ける(GCの発生を避ける)
・UpdateやLateUpdate等のコールバックを減らす
 

参考記事: 【Unity道場】パフォーマンス最適化の
ポイント
https://speakerdeck.com/unitydojo/unitydao-chang-pahuomansuzui-shi-hua-false-pointo
 
 

25
28
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
28