From cb93a3bee31512311ceb3a47d7d82ce84e396c66 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Sun, 3 Mar 2019 18:31:12 +0100 Subject: [PATCH] minor changes --- src/entt/entity/group.hpp | 16 +-- test/benchmark/benchmark.cpp | 246 +++++++++++++++++++++++++++++++++++ 2 files changed, 252 insertions(+), 10 deletions(-) diff --git a/src/entt/entity/group.hpp b/src/entt/entity/group.hpp index 374a8d032..6f7b7bee5 100644 --- a/src/entt/entity/group.hpp +++ b/src/entt/entity/group.hpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include "../config/config.h" #include "../core/type_traits.hpp" @@ -257,15 +256,13 @@ public: */ template inline void each(Func func) const { - if constexpr(std::is_invocable_v...>) { - std::for_each(handler->begin(), handler->end(), [func = std::move(func), this](const auto entity) mutable { + for(const auto entity: *handler) { + if constexpr(std::is_invocable_v...>) { func(std::get *>(pools)->get(entity)...); - }); - } else { - std::for_each(handler->begin(), handler->end(), [func = std::move(func), this](const auto entity) mutable { + } else { func(entity, std::get *>(pools)->get(entity)...); - }); - } + } + }; } /** @@ -537,9 +534,8 @@ public: inline void each(Func func) const { auto raw = std::make_tuple((std::get *>(pools)->end() - *length)...); [[maybe_unused]] auto data = std::get<0>(pools)->sparse_set::end() - *length; - const auto cend = std::get<0>(pools)->end(); - while(std::get<0>(raw) != cend) { + for(auto next = *length; next; --next) { if constexpr(std::is_invocable_v..., std::add_lvalue_reference_t...>) { if constexpr(sizeof...(Get) == 0) { func(*(std::get>(raw)++)...); diff --git a/test/benchmark/benchmark.cpp b/test/benchmark/benchmark.cpp index 8341283be..b2e61ece5 100644 --- a/test/benchmark/benchmark.cpp +++ b/test/benchmark/benchmark.cpp @@ -380,6 +380,252 @@ TEST(Benchmark, IterateTwoComponentsRuntime1MOne) { }); } +TEST(Benchmark, IterateThreeComponents1M) { + entt::registry<> registry; + + std::cout << "Iterating over 1000000 entities, three components" << std::endl; + + for(std::uint64_t i = 0; i < 1000000L; i++) { + const auto entity = registry.create(); + registry.assign(entity); + registry.assign(entity); + registry.assign>(entity); + } + + auto test = [®istry](auto func) { + timer timer; + registry.view>().each(func); + timer.elapsed(); + }; + + test([](const auto &...) {}); + test([](auto &... comp) { + ((comp.x = {}), ...); + }); +} + +TEST(Benchmark, IterateThreeComponents1MHalf) { + entt::registry<> registry; + + std::cout << "Iterating over 1000000 entities, three components, half of the entities have all the components" << std::endl; + + for(std::uint64_t i = 0; i < 1000000L; i++) { + const auto entity = registry.create(); + registry.assign(entity); + registry.assign>(entity); + + if(i % 2) { + registry.assign(entity); + } + } + + auto test = [®istry](auto func) { + timer timer; + registry.view>().each(func); + timer.elapsed(); + }; + + test([](const auto &...) {}); + test([](auto &... comp) { + ((comp.x = {}), ...); + }); +} + +TEST(Benchmark, IterateThreeComponents1MOne) { + entt::registry<> registry; + + std::cout << "Iterating over 1000000 entities, three components, only one entity has all the components" << std::endl; + + for(std::uint64_t i = 0; i < 1000000L; i++) { + const auto entity = registry.create(); + registry.assign(entity); + registry.assign>(entity); + + if(i == 5000000L) { + registry.assign(entity); + } + } + + auto test = [®istry](auto func) { + timer timer; + registry.view>().each(func); + timer.elapsed(); + }; + + test([](const auto &...) {}); + test([](auto &... comp) { + ((comp.x = {}), ...); + }); +} + +TEST(Benchmark, IterateThreeComponentsNonOwningGroup1M) { + entt::registry<> registry; + registry.group<>(entt::get); + + std::cout << "Iterating over 1000000 entities, three components, non owning group" << std::endl; + + for(std::uint64_t i = 0; i < 1000000L; i++) { + const auto entity = registry.create(); + registry.assign(entity); + registry.assign(entity); + registry.assign>(entity); + } + + auto test = [®istry](auto func) { + timer timer; + registry.group<>(entt::get>).each(func); + timer.elapsed(); + }; + + test([](const auto &...) {}); + test([](auto &... comp) { + ((comp.x = {}), ...); + }); +} + +TEST(Benchmark, IterateThreeComponentsFullOwningGroup1M) { + entt::registry<> registry; + registry.group>(); + + std::cout << "Iterating over 1000000 entities, three components, full owning group" << std::endl; + + for(std::uint64_t i = 0; i < 1000000L; i++) { + const auto entity = registry.create(); + registry.assign(entity); + registry.assign(entity); + registry.assign>(entity); + } + + auto test = [®istry](auto func) { + timer timer; + registry.group>().each(func); + timer.elapsed(); + }; + + test([](const auto &...) {}); + test([](auto &... comp) { + ((comp.x = {}), ...); + }); +} + +TEST(Benchmark, IterateThreeComponentsPartialOwningGroup1M) { + entt::registry<> registry; + registry.group(entt::get>); + + std::cout << "Iterating over 1000000 entities, three components, partial owning group" << std::endl; + + for(std::uint64_t i = 0; i < 1000000L; i++) { + const auto entity = registry.create(); + registry.assign(entity); + registry.assign(entity); + registry.assign>(entity); + } + + auto test = [®istry](auto func) { + timer timer; + registry.group(entt::get>).each(func); + timer.elapsed(); + }; + + test([](const auto &...) {}); + test([](auto &... comp) { + ((comp.x = {}), ...); + }); +} + +TEST(Benchmark, IterateThreeComponentsRuntime1M) { + entt::registry<> registry; + + std::cout << "Iterating over 1000000 entities, three components, runtime view" << std::endl; + + for(std::uint64_t i = 0; i < 1000000L; i++) { + const auto entity = registry.create(); + registry.assign(entity); + registry.assign(entity); + registry.assign>(entity); + } + + auto test = [®istry](auto func) { + using component_type = typename entt::registry<>::component_type; + component_type types[] = { registry.type(), registry.type(), registry.type>() }; + + timer timer; + registry.runtime_view(std::begin(types), std::end(types)).each(func); + timer.elapsed(); + }; + + test([](auto) {}); + test([®istry](auto entity) { + registry.get(entity).x = {}; + registry.get(entity).x = {}; + registry.get>(entity).x = {}; + }); +} + +TEST(Benchmark, IterateThreeComponentsRuntime1MHalf) { + entt::registry<> registry; + + std::cout << "Iterating over 1000000 entities, three components, half of the entities have all the components, runtime view" << std::endl; + + for(std::uint64_t i = 0; i < 1000000L; i++) { + const auto entity = registry.create(); + registry.assign(entity); + registry.assign>(entity); + + if(i % 2) { + registry.assign(entity); + } + } + + auto test = [®istry](auto func) { + using component_type = typename entt::registry<>::component_type; + component_type types[] = { registry.type(), registry.type(), registry.type>() }; + + timer timer; + registry.runtime_view(std::begin(types), std::end(types)).each(func); + timer.elapsed(); + }; + + test([](auto) {}); + test([®istry](auto entity) { + registry.get(entity).x = {}; + registry.get(entity).x = {}; + registry.get>(entity).x = {}; + }); +} + +TEST(Benchmark, IterateThreeComponentsRuntime1MOne) { + entt::registry<> registry; + + std::cout << "Iterating over 1000000 entities, three components, only one entity has all the components, runtime view" << std::endl; + + for(std::uint64_t i = 0; i < 1000000L; i++) { + const auto entity = registry.create(); + registry.assign(entity); + registry.assign>(entity); + + if(i == 5000000L) { + registry.assign(entity); + } + } + + auto test = [®istry](auto func) { + using component_type = typename entt::registry<>::component_type; + component_type types[] = { registry.type(), registry.type(), registry.type>() }; + + timer timer; + registry.runtime_view(std::begin(types), std::end(types)).each(func); + timer.elapsed(); + }; + + test([](auto) {}); + test([®istry](auto entity) { + registry.get(entity).x = {}; + registry.get(entity).x = {}; + registry.get>(entity).x = {}; + }); +} + TEST(Benchmark, IterateFiveComponents1M) { entt::registry<> registry;