86
87

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Unity】Unite 2015「Unity パフォーマンス・チューニング」レポート

Last updated at Posted at 2015-04-23

レポート一覧

講演ファイル

LOADING - ASYNCHRONOUSLY

  • 非同期読み込みのAPI
    • Applicalion.LoadLevelAsync
    • AssetBundle.LoadAsync
    • Resources.LoadAsync(5.0)

LOADING SCENES - MEMORY

  • シーン遷移時は古いシーンと新しいシーンが同時にメモリに載る
    • 新しいシーンを読み込む前に空のシーンを読み込むことで回避できる
    • ただし、デメリットもある
    • 古いシーンで使っていて新しいシーンでも使う予定のアセットをアンロードしてしまう

LOADING - SERIALIZATION

  • Unityは独自のシリアライズの機能を持っている
  • Unityのシリアライズは高速
    • 下位互換性があるがそちらのスピードは遅い
  • もともとはかなり遅かった
    • リフレクションをその場でやっていたから
    • 4.5以降で改善

LOADING - ASSETBUNDLE

  • 自分の好きな形でパッキングできる
  • サイズの最適化ができる
  • プレイヤー側で制約がある場合に有用
  • ビルド時間の最適化になる
  • ローカル、Webサーバから読み込める
  • WWW.LoadFromCacheOrDownload
    ↑これを使ってくださいとのこと

UNLOADING

  • 5.0においてオブジェクトの削除が改善された
    • オーバーヘッドが小さくなりました
    • クリーンナップがバックグラウンドで行われる
    • アセットはGCが走るまで残っている
    • ガタツキに繋がらないようにいいタイミングで使うこと
  • 主導でGCを起動してもいい
    • GC.Collect
    • Resources.UnloadUnusedAssets
  • 安全な仕組みがない
    • アセットが使われているかどうかを判断する機能がない
    • エディタなら依存関係がわかるが・・・

GC PERFORMANCE

  • GC.Collectによってスパイクが起きる
  • 仕組みを理解しよう
    • Mark and sweep型
    • staticオブジェクトからスタック、ヒープをスキャンしていく
    • 分散しているとランダムアクセスで何度もアクセスしてしまう

GC OPTINMATIONS

  • GCがあまり動かないようにするためには
    • データのレイアウトを考えること
    • リファレンスが密に行われること
    • classではなくstructを使用すること
  • GCが起動する理由
    • ヒープのメモリが不足している場合
    • ヒープは残っているけど割り当てがたくさんある場合

REDUCE GC WORK

  • リファレンスするようなデータをパックする
  • classの代わりにstructにするとすべてインラインになる
  • classはフラグメンテーションが起きてしまう
  • structのほうがキャッシュパフォーマンス的にいい
  • データを順番に並べる
class Character
{
    public string Name;
    public Vector3 Pos;
}
Character[] characters;
struct Character
{
    public string Name;
    public Vector3 Pos;
}
Character[] characters;

RESULTS

  • GC for array length 1,000,000 characters on MBP
    • Class with randomized memory locations: 35ms
    • Class with linear memory: 20ms
    • Structs: 10ms
    • Struct and no String: 0.18ms
  • stringを完全に無くすとかかった時間が短縮された

MINIMIZING MANAGED ALLOCATIONS

  • OnGUIは使わないこと

AVOIDING ALLOCATIOS

  • 関数の中で配列の割り当てをせずプールすること

POOLING

  • 事前にプールの割り当ては行っていくように

POOLING - HOW?

  • SetActiveでオブジェクトを使い回す
  • Dictionaryは使わず配列を使うように
  • 5.0においてインスタンス化の時間が改善、破棄も改善
  • SetActiveとかも50%くらい速度が改善されている

GENERAL PERFORMANCE

  • Findは使わないように
    • Inspectorで設定することでスピードが上がる、
      安定する、検索漏れがなくなる
  • 過剰な遷移を避ける
  • MonoBehaviourのUpdateの数を減らす
    • 1,000個のMonoBehaviourのUpdateを呼び出すのではなく
      1つのMonoBehaviourのUpdateから1,000個のUpdateを呼び出す
    • 1つのゲームオブジェクトで複数のコンポーネントを管理するイメージ
  • Componentとかゲームオブジェクトはキャッシュする
    • すべてMonoBehaviourを使う必要はない
    • MonoBehaviourはかなり負荷が高い
    • 通常のC#を使うこと
    • ゲームオブジェクトも同じことがいえる
    • positionとかtransformが必要だったとしても
      C#でクラスを用意することも必要
    • Unityの機能をすべて使わなくてもいい
  • たくさんの子オブジェクトの更新は負荷が高い
    • エディタ上でちゃんとHierarchyを整理しよう
    • transformのオーバーヘッドに注意

まとめ

  • 非同期でロードしよう
  • オブジェクトを再利用すること
  • キャッシュして繰り返し作業しないように
  • 自分が何を実装しているのかによってボトルネックが何かは変わってくるので
    ちゃんとプロファイラーをみて改善策を選択すること
    • 他の人のアドバイスを聞くよりも自分のゲームのプロファイラを信じること
86
87
0

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
86
87

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?