entt: Performance regression in basic_registry::ctx()
Hello! I have been working on a project for a while using EnTT 3.4.0, and recently upgraded to EnTT 3.8.1. The code migration was not very difficult (thanks!), however there seem to have been a significant performance regression in the basic_registry::ctx() function.
Below are excerpts of a linux perf output before and after migration. These were collected in Debug mode with no optimisation to preserve the full call graph, but the relative performance hit from switching to 3.8.1 is about the same (~50% overall increased runtime) in both Debug and Release configurations.
There is quite a lot of changes listed in the release notes, so I can’t pin point which could have triggered this. But from the call graph, it seems that ctx() is now using any under the hood, and that appears to be the main cause of the overhead. Is this an expected regression, i.e., should I accept that ctx() is now slower and cache the output rather than query it all the time?
EnTT 3.4.0:
--6.78%--entt::basic_registry<entt::entity>::ctx<game::hex_size>
|
--6.71%--entt::basic_registry<entt::entity>::try_ctx<game::hex_size>
|
--5.55%--std::find_if<__gnu_cxx::__normal_iterator<entt::basic_registry<entt::entity>::variable_data const*, std::vector<entt::basic_registry<entt::entity>::variable_data, std::allocator<en>
|
--5.37%--std::__find_if<__gnu_cxx::__normal_iterator<entt::basic_registry<entt::entity>::variable_data const*, std::vector<entt::basic_registry<entt::entity>::variable_data, std:>
|
--4.83%--std::__find_if<__gnu_cxx::__normal_iterator<entt::basic_registry<entt::entity>::variable_data const*, std::vector<entt::basic_registry<entt::entity>::variable>
|
--3.29%--__gnu_cxx::__ops::_Iter_pred<entt::basic_registry<entt::entity>::try_ctx<game::hex_size>() const::{lambda(auto:1&&)#1}>::operator()<__gnu_cxx::__no>
|
--2.26%--entt::basic_registry<entt::entity>::try_ctx<game::hex_size>() const::{lambda(auto:1&&)#1}::operator()<entt::basic_registry<entt::entity>>
EnTT 3.8.1:
--21.46%--entt::basic_registry<entt::entity>::ctx<game::hex_size>
|
|--19.28%--std::find_if<__gnu_cxx::__normal_iterator<entt::basic_any<0ul, 16ul> const*, std::vector<entt::basic_any<0ul, 16ul>, std::allocator<entt::basic_any<0ul, 16ul> > > >, entt::basic_registry<ent>
| |
| --18.87%--std::__find_if<__gnu_cxx::__normal_iterator<entt::basic_any<0ul, 16ul> const*, std::vector<entt::basic_any<0ul, 16ul>, std::allocator<entt::basic_any<0ul, 16ul> > > >, __gnu_cxx::>
| |
| --18.66%--std::__find_if<__gnu_cxx::__normal_iterator<entt::basic_any<0ul, 16ul> const*, std::vector<entt::basic_any<0ul, 16ul>, std::allocator<entt::basic_any<0ul, 16ul> > > >, >
| |
| --17.19%--__gnu_cxx::__ops::_Iter_pred<entt::basic_registry<entt::entity>::ctx<game::hex_size>() const::{lambda(auto:1&&)#1}>::operator()<__gnu_cxx::__normal_iterator<>
| |
| |--16.27%--entt::basic_registry<entt::entity>::ctx<game::hex_size>() const::{lambda(auto:1&&)#1}::operator()<entt::basic_any<0ul, 16ul> const&>
| | |
| | |--12.99%--entt::basic_any<0ul, 16ul>::type
| | | |
| | | |--1.77%--entt::type_info::type_info
| | | | |
| | | | |--0.72%--entt::type_info::type_info
| | | | |
| | | | --0.59%--std::basic_string_view<char, std::char_traits<char> >::basic_string_view
| | | |
| | | |--0.69%--entt::basic_any<0ul, 16ul>::basic_vtable<game::editor_mode>
| | | |
| | | |--0.66%--entt::basic_any<0ul, 16ul>::basic_vtable<game::current_player>
| | | | |
| | | | --0.51%--entt::type_id<game::current_player>
| | | |
| | | |--0.66%--entt::basic_any<0ul, 16ul>::basic_vtable<game::hex_size>
| | | |
| | | |--0.64%--entt::basic_any<0ul, 16ul>::basic_vtable<game::game_paused>
| | | |
| | | |--0.64%--entt::basic_any<0ul, 16ul>::basic_vtable<game::status_list>
| | | |
| | | |--0.63%--entt::basic_any<0ul, 16ul>::basic_vtable<game::stage>
| | | |
| | | |--0.62%--entt::basic_any<0ul, 16ul>::basic_vtable<trade::cargo_container_template_list>
| | | |
| | | |--0.59%--entt::basic_any<0ul, 16ul>::basic_vtable<game::tool_list>
| | | |
| | | |--0.58%--entt::basic_any<0ul, 16ul>::basic_vtable<game::ship_template_list>
| | | |
| | | |--0.57%--entt::basic_any<0ul, 16ul>::basic_vtable<game::time>
| | | |
| | | |--0.56%--entt::basic_any<0ul, 16ul>::basic_vtable<starsystem::delta_network>
| | | |
| | | |--0.56%--entt::basic_any<0ul, 16ul>::basic_vtable<trade::goods_list>
| | | |
| | | |--0.56%--entt::basic_any<0ul, 16ul>::basic_vtable<orders::order_template_list>
| | | |
| | | |--0.54%--entt::basic_any<0ul, 16ul>::basic_vtable<game::current_tool>
| | | |
| | | |--0.53%--entt::basic_any<0ul, 16ul>::basic_vtable<game::viewed_starsystem>
| | | |
| | | |--0.52%--entt::basic_any<0ul, 16ul>::basic_vtable<game::view_zoom_pan>
| | | |
| | | --0.52%--entt::basic_any<0ul, 16ul>::basic_vtable<game::hovered>
| | |
| | --0.94%--entt::type_info::operator==
| |
| --0.63%--__gnu_cxx::__normal_iterator<entt::basic_any<0ul, 16ul> const*, std::vector<entt::basic_any<0ul, 16ul>, std::allocator<entt::basic_any<0ul, 16ul> >>
|
--1.28%--entt::any_cast<game::hex_size const&, 0ul, 16ul>
|
--1.20%--entt::any_cast<game::hex_size const, 0ul, 16ul>
|
--0.70%--entt::basic_any<0ul, 16ul>::type
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 20 (20 by maintainers)
Commits related to this issue
- registry: improved `ctx` and the like (close #782) — committed to skypjack/entt by skypjack 3 years ago
- registry: improved `ctx` and the like (close #782) — committed to skypjack/entt by skypjack 3 years ago
- any (close #782): * make const type_info * a first citizen * further reduce vtable size — committed to skypjack/entt by skypjack 3 years ago
Yep, that commit fixes the issue for me! (edit: thank you for spending the time to look into this 😃)
Yet another commit on
wip, this time it’s close to your last suggestion. Briefly, I copied the approach of the standard library for whichtypeidreturns objects with static storage duration. Then I’ve added a top-level pointer to atype_infoinany. Can I ask you to give it a try and let me know? It would be really great.