LoginSignup
12
9

More than 5 years have passed since last update.

Unity Null Check高速化

Posted at

コードを書いていてnullチェックをすることはかなり多い。
1個1個の処理は小さくても、何千個ものオブジェクトで毎フレームnullチェックしているようでは処理時間を無駄に使っている
どうすれば処理時間を軽減できるか検証した

結論

何も考えずif(target != null)を使え

検証方法

Unityバージョン 5.5.0f3

3つの手法で検証した
- if(target != null)
- if(object.ReferenceEquals(target , null) == false )
- try - catch

対象オブジェクトがnullでない場合

NullTest.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NullTest : MonoBehaviour 
{   
    readonly int COUNT = 10000000;

    public class TestClass
    {
        public TestClass(){}

        public void Test (){}
    };

    TestClass _TestClass = new TestClass();

    // Update is called once per frame
    void Update () 
    {
        if (Input.GetKeyDown (KeyCode.A)) {

            float startTime = 0f;

            startTime = Time.realtimeSinceStartup;

            for (int i = 0; i < COUNT; i++) {
                _TestClass.Test ();    //nullチェックなし
            }

            float lap0 = Time.realtimeSinceStartup - startTime;

            startTime = Time.realtimeSinceStartup;

            for (int i = 0; i < COUNT; i++) {
                if (_TestClass != null) {
                    _TestClass.Test ();
                }
            }

            float lap1 = Time.realtimeSinceStartup - startTime;

            startTime = Time.realtimeSinceStartup;

            for (int i = 0; i < COUNT; i++) {
                if (object.ReferenceEquals(_TestClass,null)==false) {
                    _TestClass.Test ();
                }
            }

            float lap2 = Time.realtimeSinceStartup - startTime;

            startTime = Time.realtimeSinceStartup;

            for (int i = 0; i < COUNT; i++) {
                try{
                    _TestClass.Test();
                }
                catch(System.Exception e) {

                }
            }

            float lap3 = Time.realtimeSinceStartup - startTime;
            Debug.Log (lap0);
            Debug.Log (lap1);
            Debug.Log (lap2);
            Debug.Log (lap3);
        }
    }
}


手法 実行時間[sec]
(参考) nullチェックなし 0.1567643
if(target != null) 0.163532
if(object.ReferenceEquals(target , null) == false ) 0.2293189
try-catch 0.1630554

try-catchがわずかに早い

対象オブジェクトがnullの場合

上記コードの_TestClassをnullにして検証

手法 実行時間
if(target != null) 0.07411861
if(object.ReferenceEquals(target , null) == false) 0.1276345
try-catch 遅すぎて実行不可

try-catchはnullだった場合にとても遅くなる

参考

object.ReferenceEqualsは癖がある模様
object.ReferenceEquals(someObject, null) の方が someObject == null より早い…が、盲目的に使うのは危険

12
9
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
12
9