Skip to content

Commit

Permalink
feat: add event benchmarks
Browse files Browse the repository at this point in the history
- mustache benchmark
- entt event with stable pointer
  • Loading branch information
abeimler committed Apr 7, 2024
1 parent 364f265 commit b9819f9
Show file tree
Hide file tree
Showing 11 changed files with 278 additions and 11 deletions.
14 changes: 14 additions & 0 deletions benchmark/benchmarks/entt-extended/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,20 @@ target_link_libraries(ecs-benchmark-entt-extended-event-emit PRIVATE ecs-benchma
# @NOTE: add libs for example here
target_link_libraries(ecs-benchmark-entt-extended-event-emit PRIVATE ecs-benchmark-example-entt)

set(INCLUDE_DIR "include") # must be relative paths
# NOTE: rename project in "ecs-benchmark-myecs"
add_executable(
ecs-benchmark-entt-extended-event-emit-stable
# NOTE: add new benchmarks here
EnttStableEventEmitBenchmarkSuite.cpp EnttStableEventEmitBenchmarkSuite.h)
target_include_directories(
ecs-benchmark-entt-extended-event-emit-stable
PRIVATE "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>" "$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/${INCLUDE_DIR}>"
"$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/${INCLUDE_DIR}>" "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/${INCLUDE_DIR}>")
target_link_libraries(ecs-benchmark-entt-extended-event-emit-stable PRIVATE project_warnings project_options)
target_link_libraries(ecs-benchmark-entt-extended-event-emit-stable PRIVATE ecs-benchmark)
# @NOTE: add libs for example here
target_link_libraries(ecs-benchmark-entt-extended-event-emit-stable PRIVATE ecs-benchmark-example-entt)

set(INCLUDE_DIR "include") # must be relative paths
# NOTE: rename project in "ecs-benchmark-myecs"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef ECS_BENCHMARKS_ENTTBENCHMARK_H_
#define ECS_BENCHMARKS_ENTTBENCHMARK_H_
#ifndef ECS_BENCHMARKS_ENTTEVENTEMITBENCHMARK_H_
#define ECS_BENCHMARKS_ENTTEVENTEMITBENCHMARK_H_

#include "ExtendedECSBenchmark.h"
#include "entt/EnttApplication.h"
Expand Down Expand Up @@ -84,4 +84,4 @@ class EnttEventEmitBenchmarkSuite final

} // namespace ecs::benchmarks::entt

#endif // ECS_BENCHMARKS_ENTTBENCHMARK_H_
#endif // ECS_BENCHMARKS_ENTTEVENTEMITBENCHMARK_H_
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include "EnttStableEventEmitBenchmarkSuite.h"

static ecs::benchmarks::entt::EnttStableEventEmitBenchmarkSuite
benchmark_suite({.add_more_complex_system = ecs::benchmarks::base::add_more_complex_system_t::UseMoreComplexSystems,
.version = ENTT_VERSION});

static void BM_TriggerAndUpdateEventsViaDispatcherWithMixedEntities(benchmark::State& state) {
benchmark_suite.BM_TriggerAndUpdateEventsViaDispatcherWithMixedEntities(state);
}
BENCHMARK(BM_TriggerAndUpdateEventsViaDispatcherWithMixedEntities)->Apply(ecs::benchmarks::base::BEDefaultArguments);
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#ifndef ECS_BENCHMARKS_ENTTSTABLEEVENTBENCHMARK_H_
#define ECS_BENCHMARKS_ENTTSTABLEEVENTBENCHMARK_H_

#include "ExtendedECSBenchmark.h"
#include "entt/StableEnttApplication.h"
#include "entt/entities/HeroMonsterEntityFactory.h"
#include "entt/entities/StableEntityFactory.h"
#include <utility>

namespace ecs::benchmarks::entt {

struct Event {
using ComponentOne = ecs::benchmarks::entt::components::StablePositionComponent;
using ComponentTwo = ecs::benchmarks::entt::components::StableVelocityComponent;

ComponentOne* comp1;
ComponentTwo* comp2;
};

struct DummyListener {
public:
DummyListener(::entt::registry& registry,
::entt::dispatcher& dispatcher) : m_registry(registry), m_dispatcher(dispatcher) {}

void setup() {
m_dispatcher.sink<Event>().connect<&DummyListener::receive>(*this);
}
void teardown() {
m_dispatcher.sink<Event>().disconnect<&DummyListener::receive>(*this);
}

void receive(Event& event) {
benchmark::DoNotOptimize(*event.comp1);
benchmark::DoNotOptimize(*event.comp2);
//benchmark::DoNotOptimize(event);
}

private:
::entt::registry& m_registry;
::entt::dispatcher& m_dispatcher;
};

class EnttStableEventEmitBenchmarkSuite final
: public ecs::benchmarks::base::ExtendedECSBenchmark<"entt (emit, stable)", StableEnttApplication, entities::StableEntityFactory,
entities::HeroMonsterEntityFactory> {
public:
EnttStableEventEmitBenchmarkSuite() = default;

explicit EnttStableEventEmitBenchmarkSuite(ecs::benchmarks::base::ESCBenchmarkOptions options)
: ExtendedECSBenchmark(std::move(options)) {}

void BM_TriggerAndUpdateEventsViaDispatcherWithMixedEntities(benchmark::State& state) {
using ComponentOne = ecs::benchmarks::entt::components::StablePositionComponent;
using ComponentTwo = ecs::benchmarks::entt::components::StableVelocityComponent;

const auto nentities = static_cast<size_t>(state.range(0));
StableEnttApplication::Application app(this->m_options.add_more_complex_system);
EntityManager& registry = app.getEntities();
std::vector<Entity> entities;
const base::ComponentsCounter components_counter =
this->template createEntitiesWithMixedComponents<entities::StableEntityFactory>(registry, nentities, entities);

::entt::dispatcher dispatcher{};
DummyListener listener (registry, dispatcher);

listener.setup();

auto view = registry.template view<ComponentOne, ComponentTwo>();
for (auto _ : state) {
view.each([&](auto /*entity*/, auto& comp1, auto& comp2) {
//dummy_each(comp1, comp2);
dispatcher.trigger<Event>({.comp1 = &comp1, .comp2 = &comp2});
});
}

listener.teardown();

this->setCounters(state, entities, components_counter);
//state.counters["events_count"] = static_cast<double>(entities.size());
}
};

} // namespace ecs::benchmarks::entt

#endif // ECS_BENCHMARKS_ENTTSTABLEEVENTBENCHMARK_H_
17 changes: 16 additions & 1 deletion benchmark/benchmarks/mustache-extended/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,21 @@ target_include_directories(
"$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/${INCLUDE_DIR}>" "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/${INCLUDE_DIR}>")
target_link_libraries(ecs-benchmark-mustache-extended PRIVATE project_warnings project_options)
target_link_libraries(ecs-benchmark-mustache-extended PRIVATE ecs-benchmark)

# @NOTE: add libs for example here
target_link_libraries(ecs-benchmark-mustache-extended PRIVATE ecs-benchmark-example-mustache)


set(INCLUDE_DIR "include") # must be relative paths
# NOTE: rename project in "ecs-benchmark-myecs"
add_executable(
ecs-benchmark-mustache-extended-event
# NOTE: add new benchmarks here
MustacheEventBenchmarkSuite.cpp MustacheEventBenchmarkSuite.h)
target_include_directories(
ecs-benchmark-mustache-extended-event
PRIVATE "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>" "$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/${INCLUDE_DIR}>"
"$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/${INCLUDE_DIR}>" "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/${INCLUDE_DIR}>")
target_link_libraries(ecs-benchmark-mustache-extended-event PRIVATE project_warnings project_options)
target_link_libraries(ecs-benchmark-mustache-extended-event PRIVATE ecs-benchmark)
# @NOTE: add libs for example here
target_link_libraries(ecs-benchmark-mustache-extended-event PRIVATE ecs-benchmark-example-mustache)
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include "MustacheEventBenchmarkSuite.h"

static ecs::benchmarks::mustache::MustacheEventBenchmarkSuite benchmark_suite({
.add_more_complex_system = ecs::benchmarks::base::add_more_complex_system_t::UseMoreComplexSystems,
.version = std::nullopt,
});

static void BM_PostAndUpdateEventsViaReceiverWithMixedEntities(benchmark::State& state) {
benchmark_suite.BM_PostAndUpdateEventsViaReceiverWithMixedEntities(state);
}
BENCHMARK(BM_PostAndUpdateEventsViaReceiverWithMixedEntities)->Apply(ecs::benchmarks::base::BEDefaultArguments);
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#ifndef ECS_BENCHMARKS_MUSTACHEEVENTBENCHMARK_H_
#define ECS_BENCHMARKS_MUSTACHEEVENTBENCHMARK_H_

#include "ExtendedECSBenchmark.h"
#include "mustache/MustacheApplication.h"
#include "mustache/entities/EntityFactory.h"
#include "mustache/entities/HeroMonsterEntityFactory.h"
#include "mustache/systems/DataSystem.h"
#include "mustache/systems/MoreComplexSystem.h"
#include "mustache/systems/MovementSystem.h"
#include <utility>

namespace ecs::benchmarks::mustache {

struct Event {
::mustache::Entity entity;
};

struct DummyEventSystem : public ::mustache::System<DummyEventSystem>, public ::mustache::Receiver<Event> {
void onConfigure(::mustache::World& world, ::mustache::SystemConfig& config) override {
/// FIXME: Error at mustache/ecs/event_manager.hpp:85:22
//world.events().subscribe<Event>(this);
world.events().subscribe<Event>([&](const Event &e) {
using ComponentOne = ecs::benchmarks::base::components::PositionComponent;
using ComponentTwo = ecs::benchmarks::base::components::VelocityComponent;
benchmark::DoNotOptimize(*world.entities().getComponent<ComponentOne,
::mustache::FunctionSafety::kUnsafe>(e.entity));
benchmark::DoNotOptimize(*world.entities().getComponent<ComponentTwo,
::mustache::FunctionSafety::kUnsafe>(e.entity));
});
}
void onEvent(const Event &e) {
benchmark::DoNotOptimize(e.entity.id());
}
};

class PostEventSystem : public ::mustache::System<PostEventSystem> {
public:
void onUpdate(::mustache::World& world) override {
using ComponentOne = ecs::benchmarks::base::components::PositionComponent;
using ComponentTwo = ecs::benchmarks::base::components::VelocityComponent;

world.entities().forEach([&](::mustache::Entity entity, const ComponentOne& pos, const ComponentTwo& vel){
world.events().post(Event{entity});
});
}
};


class MustacheEventBenchmarkSuite final
: public ecs::benchmarks::base::ExtendedECSBenchmark<"mustache (event)", MustacheApplication, entities::EntityFactory,
entities::HeroMonsterEntityFactory> {
public:
MustacheEventBenchmarkSuite() = default;

explicit MustacheEventBenchmarkSuite(ecs::benchmarks::base::ESCBenchmarkOptions options)
: ExtendedECSBenchmark(std::move(options)) {}


void BM_PostAndUpdateEventsViaReceiverWithMixedEntities(benchmark::State& state) {
using ComponentOne = ecs::benchmarks::base::components::PositionComponent;
using ComponentTwo = ecs::benchmarks::base::components::VelocityComponent;

const auto nentities = static_cast<size_t>(state.range(0));
::mustache::World world;
auto& manager = world.entities();
std::vector<Entity> entities;
const base::ComponentsCounter components_counter =
this->template createEntitiesWithMixedComponents<entities::EntityFactory>(manager, nentities, entities);

const auto consumeEvent = [&](const Event &e) {
using ComponentOne = ecs::benchmarks::base::components::PositionComponent;
using ComponentTwo = ecs::benchmarks::base::components::VelocityComponent;
benchmark::DoNotOptimize(*world.entities().getComponent<ComponentOne,
::mustache::FunctionSafety::kUnsafe>(e.entity));
benchmark::DoNotOptimize(*world.entities().getComponent<ComponentTwo,
::mustache::FunctionSafety::kUnsafe>(e.entity));
};
///@FIXME: add onUpdate ?
world.systems().addSystem<PostEventSystem>();
//world.systems().addSystem<DummyEventSystem>();
world.events().subscribe<Event>(consumeEvent);
world.init();

for (auto _ : state) {
world.update();
}

this->setCounters(state, entities, components_counter);
//state.counters["events_count"] = static_cast<double>(entities.size());
}
};

} // namespace ecs::benchmarks::mustache

#endif // ECS_BENCHMARKS_MUSTACHEEVENTBENCHMARK_H_
20 changes: 19 additions & 1 deletion plot.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -250,14 +250,23 @@
"color": "#66ccff"
},
"entt (emit)": {
"name": "EnTT (trigger)",
"name": "EnTT (emit)",
"author": "@skypjack",
"description": "EnTT is a header-only, tiny and easy to use library for game programming and much more written in modern C++.",
"version": "v3.13.1",
"link": "https://github.com/skypjack/entt",
"skip_candidate": true,
"color": "#0099ff"
},
"entt (emit, stable)": {
"name": "EnTT (emit, stable)",
"author": "@skypjack",
"description": "EnTT is a header-only, tiny and easy to use library for game programming and much more written in modern C++.",
"version": "v3.13.1",
"link": "https://github.com/skypjack/entt",
"skip_candidate": true,
"color": "#3994d1"
},
"ginseng": {
"name": "Ginseng",
"author": "@apples",
Expand All @@ -274,6 +283,15 @@
"link": "https://github.com/kirillochnev/mustache",
"color": "#ff66cc"
},
"mustache (event)": {
"name": "mustache",
"author": "@kirillochnev",
"description": "A fast, modern C++ Entity Component System",
"version": "0.2 (Feb 2024)",
"link": "https://github.com/kirillochnev/mustache",
"skip_candidate": true,
"color": "#ff66cc"
},
"openecs": {
"name": "OpenEcs",
"author": "@Gronis",
Expand Down
16 changes: 12 additions & 4 deletions src/openecs/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
# add dependencies FIXME: Failed to unstash changes ... Encountered 2 file(s) that should have been pointers, but weren't:
# img/component_memory_pool.png img/componentmask_version_vector.png CPMAddPackage( NAME OpenECS VERSION 0.1.101 GITHUB_REPOSITORY
# Gronis/OpenEcs # TODO: set current version, use master (no release version) GIT_TAG master DOWNLOAD_ONLY True ) if(OpenECS_ADDED)
# add_library(OpenEcs INTERFACE) target_include_directories(OpenEcs SYSTEM INTERFACE ${OpenECS_SOURCE_DIR}/include) endif() workaround: use
# local files, see libs/
# img/component_memory_pool.png img/componentmask_version_vector.png
## CPMAddPackage( NAME OpenECS
## VERSION 0.1.101
## GITHUB_REPOSITORY
## Gronis/OpenEcs
## # TODO: set current version, use master (no release version)
## GIT_TAG master
## DOWNLOAD_ONLY True)
## if(OpenECS_ADDED)
## add_library(OpenEcs INTERFACE) target_include_directories(OpenEcs SYSTEM INTERFACE ${OpenECS_SOURCE_DIR}/include)
## endif()
# workaround: use local files, see libs/

set(INCLUDE_DIR "include") # must be relative paths
# NOTE: rename project in "${CMAKE_PROJECT_NAME}-example-myecs"
Expand Down
6 changes: 4 additions & 2 deletions taskfiles/Plot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,10 @@ tasks:
{{.PROJECT_DIR}}/reports/entt-extended-event.json
{{.PROJECT_DIR}}/reports/entt-extended-event-comp.json
{{.PROJECT_DIR}}/reports/entt-extended-event-emit.json
{{.PROJECT_DIR}}/reports/flecs-extended-event-emit.json
#{{.PROJECT_DIR}}/reports/flecs-extended-event.json
{{.PROJECT_DIR}}/reports/entt-extended-event-emit-stable.json
# {{.PROJECT_DIR}}/reports/flecs-extended-event-emit.json
# {{.PROJECT_DIR}}/reports/flecs-extended-event.json
# {{.PROJECT_DIR}}/reports/mustache-extended-event.json

extended:
- task: utils:gen-report-template
Expand Down
8 changes: 8 additions & 0 deletions taskfiles/benchmarks/Entt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ tasks:
- task: extended-event
- task: extended-event-comp
- task: extended-event-emit
- task: extended-event-emit-stable

default:
- task: utils:run-benchmark-template
Expand Down Expand Up @@ -139,4 +140,11 @@ tasks:
vars:
REPORT_NAME: entt-event-emit
BENCHMARK_NAME: entt-extended-event-emit
BENCHMARK_DIR: entt-extended

extended-event-emit-stable:
- task: utils:run-benchmark-template
vars:
REPORT_NAME: entt-event-emit-stable
BENCHMARK_NAME: entt-extended-event-emit-stable
BENCHMARK_DIR: entt-extended

0 comments on commit b9819f9

Please sign in to comment.