How can I improve the performance of instancing a scene?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Arron Washington
:warning: Old Version Published before Godot 3 was released.

I have a scene that consists of a Node2D and a Sprite. The Sprite has a 512x512 texture attached to it.

I’ve preloaded the scene in question, and I have a function that makes an instance of the scene ever time I click a button. In measuring the instancing performance, via OS.get_ticks_msec before and after the instance() call, I’ve discovered that it’s anywhere from 10ms-20ms to instance the preloaded scene.

How can I improve the performance of scene instancing?

EDIT: I’m going to be loading a large number of these scenes (in the range of 400-600), so I’d like to do so as quickly as possible.

:bust_in_silhouette: Reply From: Zylann

I tested myself to instance such a scene as you describe it, and it takes 1 millisecond to instance, at most. 90% of the time it takes 0:

var time_before = OS.get_ticks_msec()

var scene = preload("sprite_512.tscn")
var n = scene.instance()
get_parent().add_child(n)

var elapsed = OS.get_ticks_msec() - time_before
print("Ms: " + str(elapsed))

If I instance 500 of them, I effectively get 10ms of elapsed time.
But… are you really considering instancing 500 times an element that can be seen in a 512x512 pixels area? Is it for a scrolling level then? (Obviously, the player cannot see all of them at once).
If it’s for loading a level, then 10ms is nothing, tbh. And if you really want no framerate “spike” at all, you can do the loading in a thread, I believe.

A general solution to this is to load all objects once, but never destroy any of them. Instead, if you need to remove one, just hide it. If you need another to spawn, take one you previously made invisible, and show it again. That’s called “pooling”, re-using objects instead of rebuilding them.
If this is needed in general, it could be easy to implement a singleton that manages instancing of pooled scenes.

If the scene is only a Node2D and a Sprite, why not just make it a Sprite? That makes one node less to build.

The texture is 512x512, but I’m using VFrame and HFrame so that only 32px of that texture is shown.

So all the sprites on screen are using the same texture, just different frames.

Still, since I’m getting a 10ms runtime when instancing just one of these objects, and you’re not, I think it might be how my scenes are set up, or maybe it has to do with the file format I’m using as the texture. I’ll do some more homework on this.

Thanks for your help / experiment results.

If the scene is only a Node2D and a Sprite, why not just make it a Sprite? That makes one node less to build.

Will be adding other nodes eventually, but was just perf testing for now.

Arron Washington | 2016-08-24 02:22

Good advice, so I’ve accepted it as the answer.

Arron Washington | 2016-08-24 04:31