From 919bc90579862e1b7f17cc9b407d45bbdc8a5445 Mon Sep 17 00:00:00 2001 From: Dawid Drozd Date: Sat, 5 Aug 2017 13:27:35 +0200 Subject: [PATCH] Add sample performance test --- .gitignore | 1 + CMakeLists.txt | 1 + performance/CMakeLists.txt | 10 ++ performance/README.md | 31 +++++ performance/eventbus/EventBusPerformance.cpp | 129 +++++++++++++++++++ 5 files changed, 172 insertions(+) create mode 100644 performance/CMakeLists.txt create mode 100644 performance/README.md create mode 100644 performance/eventbus/EventBusPerformance.cpp diff --git a/.gitignore b/.gitignore index ddb4c89..846bc2f 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,4 @@ *.app build/ +cmake-build*/ diff --git a/CMakeLists.txt b/CMakeLists.txt index b066474..92aa95e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,3 +44,4 @@ EXPORT(TARGETS EventBus FILE EventBusConfig.cmake) ENABLE_TESTING() ADD_SUBDIRECTORY(test/) +ADD_SUBDIRECTORY(performance/) diff --git a/performance/CMakeLists.txt b/performance/CMakeLists.txt new file mode 100644 index 0000000..0074980 --- /dev/null +++ b/performance/CMakeLists.txt @@ -0,0 +1,10 @@ +# http://www.levelofindirection.com/journal/2010/12/28/unit-testing-in-c-and-objective-c-just-got-easier.html +# Thanks for CATCH! + +ADD_SUBDIRECTORY(benchmark/) + +ADD_EXECUTABLE(EventBusPerformance + eventbus/EventBusPerformance.cpp + ) + +TARGET_LINK_LIBRARIES(EventBusPerformance PUBLIC Dexode::EventBus benchmark) diff --git a/performance/README.md b/performance/README.md new file mode 100644 index 0000000..98bd0c2 --- /dev/null +++ b/performance/README.md @@ -0,0 +1,31 @@ +# Performace + +This is maybe not perfect but can show something. All result are run using RELESE build. +Why? + +Sample DEBUG run: +```commandline +Run on (8 X 3600 MHz CPU s) +2017-08-05 12:44:53 +***WARNING*** Library was built as DEBUG. Timings may be affected. +--------------------------------------------------------------- +Benchmark Time CPU Iterations +--------------------------------------------------------------- +checkSimpleNotification 293 ns 293 ns 2319171 +``` + +Sample RELEASE run: +```commandline +Run on (8 X 3600 MHz CPU s) +2017-08-05 12:45:43 +--------------------------------------------------------------- +Benchmark Time CPU Iterations +--------------------------------------------------------------- +checkSimpleNotification 6 ns 6 ns 116492914 +``` + +So below all numbers are in release. + +This library as you can read in main README.md was inspured by [CCNotificationCenter](https://github.com/cocos2d/cocos2d-x/blob/v2/cocos2dx/support/CCNotificationCenter.h) from cocos2d-x game engine. +So i want to present comparision of performance of this two. Of course this is only showcase. + diff --git a/performance/eventbus/EventBusPerformance.cpp b/performance/eventbus/EventBusPerformance.cpp new file mode 100644 index 0000000..8b92084 --- /dev/null +++ b/performance/eventbus/EventBusPerformance.cpp @@ -0,0 +1,129 @@ +// +// Created by Dawid Drozd aka Gelldur on 05.08.17. +// +#include + +#include +#include + +namespace +{ + +MAKE_NOTIFICATION(SimpleNotification, int); + +void checkSimpleNotification(benchmark::State& state) +{ + Dexode::Notifier bus; + int sum = 0; + bus.listen(getNotificationSimpleNotification(), [&](int value) + { + sum += value * 2; + }); + + while (state.KeepRunning()) + { + bus.notify(getNotificationSimpleNotification(), 2); + } +} + +void check100Listeners(benchmark::State& state) +{ + Dexode::Notifier bus; + int sum = 0; + for (int i = 0; i < 100; ++i) + { + bus.listen(getNotificationSimpleNotification(), [&](int value) + { + sum += value * 2; + }); + } + + while (state.KeepRunning()) + { + bus.notify(getNotificationSimpleNotification(), 2); + } +} + +void check1kListeners(benchmark::State& state) +{ + Dexode::Notifier bus; + int sum = 0; + for (int i = 0; i < 1000; ++i) + { + bus.listen(getNotificationSimpleNotification(), [&](int value) + { + sum += value * 2; + }); + } + + while (state.KeepRunning()) + { + bus.notify(getNotificationSimpleNotification(), 2); + } +} + +void checkNNotificationsForNListeners(benchmark::State& state, const int notificationsCount, const int listenersCount) +{ + std::mt19937 generator(311281); + std::uniform_int_distribution uniformDistribution(0, notificationsCount - 1); + + //We generate here N different notifications + std::vector> notifications; + notifications.reserve(notificationsCount); + for (int i = 0; i < notificationsCount; ++i) + { + notifications.emplace_back(691283); + } + + Dexode::Notifier bus; + int sum = 0; + //We register 1k listeners for N notifications using uniform distribution + for (int i = 0; i < listenersCount; ++i) + { + const auto& notification = notifications.at(uniformDistribution(generator)); + bus.listen(notification, [&](int value) + { + benchmark::DoNotOptimize(sum += value * 2);//we use it to prevent some? optimizations + }); + } + + //Performance area! + while (state.KeepRunning()) + { + //Pick random notification + const auto& notification = notifications.at(uniformDistribution(generator)); + bus.notify(notification, uniformDistribution(generator)); + } +} + +void check10NotificationsFor1kListeners(benchmark::State& state) +{ + checkNNotificationsForNListeners(state, 10, 1000); +} + +void check100NotificationsFor1kListeners(benchmark::State& state) +{ + checkNNotificationsForNListeners(state, 100, 1000); +} + +void check1kNotificationsFor1kListeners(benchmark::State& state) +{ + checkNNotificationsForNListeners(state, 1000, 1000); +} + +void check100NotificationsFor10kListeners(benchmark::State& state) +{ + checkNNotificationsForNListeners(state, 100, 10000); +} + +} + +BENCHMARK(checkSimpleNotification); +BENCHMARK(check100Listeners); +BENCHMARK(check1kListeners); +BENCHMARK(check10NotificationsFor1kListeners); +BENCHMARK(check100NotificationsFor1kListeners); +BENCHMARK(check1kNotificationsFor1kListeners); +BENCHMARK(check100NotificationsFor10kListeners); + +BENCHMARK_MAIN();