Search Unity

Addressables.Instantiate(key) way slower than GameObject.Instantiate?

Discussion in 'Addressables' started by MNNoxMortem, Mar 12, 2019.

  1. MNNoxMortem

    MNNoxMortem

    Joined:
    Sep 11, 2016
    Posts:
    723
    To be honest: I need to investigate and measure this further before I am able to say much about this, but is it possible that Addressables.Instantiate is waaaay slower than GameObject.Instantiate? The async nature of it changes how it feels compared to a short freeze and the code itself beeing async is difficult to compare to a simple for-loop.

    However, instantiation of a few hundred gameobjects - of the same prefab - via Addressables.Instantiate(key) looks really slow


    Compared to Object.Instantiate which is almost instant
     
    RecursiveFrog likes this.
  2. RecursiveFrog

    RecursiveFrog

    Joined:
    Mar 7, 2011
    Posts:
    350
    Anecdotally, I notice the same thing. I simply GameObject.Instantiate copies of the loaded Asset because of this. The convenience of it being synch makes it even more tempting.
     
    MNNoxMortem likes this.
  3. unity_bill

    unity_bill

    Joined:
    Apr 11, 2017
    Posts:
    1,053
    If loading a few hundred, it probably is a good idea to load via addressables, and save the reference to do sync instantiation from there.
    That being said, I would like to look into this a little. What context are you running in (player or play mode)? If play mode, which mode (packed/fast/virtual)?

    -Bill
     
  4. MNNoxMortem

    MNNoxMortem

    Joined:
    Sep 11, 2016
    Posts:
    723
    PlayMode Fast as well as Packed Build x64 and WebGL. Wen can provide a project if that helps.

    I somehow assumed the AAS would actually be clever enough to quickly return already loaded keys as I read somewhere it does ref counting and releases the memory if not needed anymore and I wanted to avoid to replicate that functionality.

    We now indeed to cache the result and it works well this way, but I guess it would really be better if the AAS would handle that, s.t. we do not need to ref count on our end (if unity does refcounting anyway already).

    Also we did improve some of our awaiting logic which reduced the difference - using now await UniRx.Async.UniTask.WhenAll() instead of awaiting every single instantiation. However, a noticable difference remains.
     
  5. unity_bill

    unity_bill

    Joined:
    Apr 11, 2017
    Posts:
    1,053
    yes, it should be doing that. We made some changes to that system in 0.6.7, and some more in our in-progress release. I'll add this to the list of things for us to check out. For the time being, we do not need a sample project, but if we do, I'll reach out.
     
    MNNoxMortem likes this.
  6. unity_bill

    unity_bill

    Joined:
    Apr 11, 2017
    Posts:
    1,053
    Also, I will add, we do far less "smarts" in fast mode. In that context, we rely on Unity's built in AssetDatabase calls. So I would not be surprised by oddities in that mode.
     
    MNNoxMortem likes this.
  7. YoyoMario

    YoyoMario

    Joined:
    Apr 8, 2013
    Posts:
    16
    What you're saying doesn't make any sense.
    First of all, when you have GameObject referenced in the inspector of your scene objects, those references are LOADED CONSTANTLY INTO RAM.
    Second of all, when you use GameObject.Instantiate, GameObject.Instantiate impact depends on the object you're trying to instantiate.
    Third of all, Asset References (Addressables) are like pointers, so when you call Addresables.Instantiate, first thing it does - is asynchronously loading the object into the RAM over some period of time (could be 1 frame, could be 50 frames or could be 1000 frames, doesn't matter), then it asynchronously instantiates the object and returns the
    AsyncOperationHandle<GameObject>: an async operation handle that contains the instantiated GameObject as the Result.
    Addressables DO NOT RETURN results instantly, they are asynchronous, meaning, you have to subscribe and accomodate your app to events.
    In the long run, this results in less bugs and better app performance.

    Meaning, Addressables Instantiate will take longer to instantiate the object but with less overhead on the current thread and your game WILL NOT stutter.
     
    mario_unity858 likes this.
  8. einWikinger

    einWikinger

    Joined:
    Jul 30, 2013
    Posts:
    97
    Still, you could just load the prefab once via the addressables API and then use plain old Instantiate() on them, and when you're done with all of them and have them destroyed, you can release the addressable handle to the prefab asset to unload all dependencies. We do this for the same reason OP ran into - it's just way faster. You have to do your own bookkeeping, sure, but if you want to fill a pool at load time, I'd rather do my own time-slicing instead of waiting on the addressable overhead which is even tied to update rate then because of the task loop.