HaxeFlixel / flixel

Free, cross-platform 2D game engine powered by Haxe and OpenFL
https://haxeflixel.com/
MIT License
1.93k stars 427 forks source link

Barely any fps on 100000 sprites that are 400x400 pixels #3104

Closed SomeGuyWhoLovesCoding closed 2 months ago

SomeGuyWhoLovesCoding commented 2 months ago

Code snippet reproducing the issue:

package;

import flixel.FlxSprite;
import flixel.FlxState;

class PlayState extends FlxState
{
    var stamp:Float = 0;

    override public function create()
    {
        for (i in 0...100000)
        {
            var spr:FlxSprite = new FlxSprite().loadGraphic('assets/image.png');
            spr.x = (i * 0.01);
            spr.alpha = 0.005;
            add(spr);
        }

        stamp = haxe.Timer.stamp();

        super.create();
    }

    override public function update(elapsed:Float)
    {
        Sys.println(1.0 / (haxe.Timer.stamp() - stamp) + ' fps');
        stamp = haxe.Timer.stamp();
        super.update(elapsed);
    }
}

(And yes I'm using haxe.Timer.stamp for time between frames.


Observed behavior: 100000 sprites gave between 7.9-9.3 fps on a 60hz monitor Expected behavior: 100000 sprites will not lag the game pretty badly (Don't mind the load times when creating all those sprites, that's not the important part)

Geokureli commented 2 months ago

Note to others: this is from our discord discussion

What I said was:

try drawing 100000 objects and then tell me that the MAIN issue there is the draw items I emphasize MAIN because you're likely gonna have more prominent issues in that case

Not one is surprised that 100000 sprites causes slowdown, your job was to determine if your hypothesis of why, is correct. You said:

I think flixel should have a pooling system with draw calls and update calls. Because, it's simply more efficient And, it keeps the gc from cleaning up every time Which caused more jitters to happen than normal So we need to have the least gc clean ups as possible It's especially faster than just doing a for loop and calling draw from there

have you learned that the slowdown is related to memory leaks from draw calls? I'm gonna guess that it isn't

SomeGuyWhoLovesCoding commented 2 months ago

The memory only leaks a bit for 400x400 pixel images but for 1024x2048 images, yes. So, I've thought of a pooling system that'll use the same function, and when you set active to false, it basically removes that function from the update pool. Otherwise, it adds back that function.

Geokureli commented 2 months ago

the system you talk about here would have no effect on memory or GC rate

Pooling is a way to reduce the number of object instantiations be recycling old instances for new ones, this code is not a pool system, nor does it prevent any object instantiation.

this code would also break many flixel games, because setting a group's active should make children inactive, but that will not happen with your code