skypjack / entt

Gaming meets modern C++ - a fast and reliable entity component system (ECS) and much more
https://github.com/skypjack/entt/wiki
MIT License
9.6k stars 844 forks source link

Debug Build Performance Issue #1112

Closed Wrathen closed 3 months ago

Wrathen commented 3 months ago

Hey!

Love the ease-of-use and the performance benefits of the EnTT but one problem I have seen so far is the Debug build performance bottlenecks caused by reg.group<T>(entt::get<...>).

I have been developing a game from scratch in C++ for over a year now and wanted to switch to more of a data-oriented design and have been trying to build everything in a new project base using EnTT for the last few days.

https://github.com/Wrathen/PathOfCPP/tree/Project_Rewrite_ECS_Ascendants

The performance benefits in the Release build is pretty noticable, up to 3 times more FPS I am getting when compared to my original implementations, which I love. But the debug builds are way way slower. Maybe I could be doing some concepts wrong so wanted to ask for help.

The main bottleneck (I think) is caused by following code snippets.

// Render Loop in Client::S_RenderEntities.cpp
auto& reg = Utils::GetRegistry();
auto group = reg.group<SpriteRendererComponent>(entt::get<TransformComponent, TextureComponent>);
group.each([](auto entity, auto& renderer, auto& transform, auto& tex) {...}

In here, even if the lambda function is empty, the performance decrease is pretty noticable on Debug builds. There are about 826 monsters in the scene + a background entity + local player entity which comes up to 828 iterations of that function (each frame) in the particular scene (https://imgur.com/a/9t4FiMq).

I have a few loops that needs to go through ALL the entities that have specific components such as this one too.

// Update Loop in Core::S_MoveEntities.cpp
auto& reg = Core::SceneMgr.GetCurrentScene()->reg;
auto group = reg.group<TransformComponent>(entt::get<StatsComponent>);
group.each([&reg](auto entity, auto& transform, auto& stats) {...}

Is there a way for me to get more FPS on Debug Builds? What could be the cause for such a difference between Debug and Release builds? I would have never thought the difference would be this much.

Thanks in advance!

P.S: Additional benchmark screenshots: https://imgur.com/a/h1ODHx6

In here, I made all the systems' loop lambda functions to return immediately on the group.each();

skypjack commented 3 months ago

I guess you are on windows and you're probably hitting its extra checks on iterators or similar. See here for further details. I usually compile in release with debug info, no matter what. Consider that groups have an initialization step on non-empty registries. That is why just creating them and returning isn't a noop. 👍

Wrathen commented 3 months ago

Oh!

I missed the FAQ section. Sorry about that. Will check it ASAP.

Thank you! ^^