Skip to content

Commit 8b5198f

Browse files
authored
Init Benchmarking
- added google-benchmark framework - basic bind().call() benchmark numbers out now. - test project renamed- RTLTestRunApp - added perf. project- RTLBenchmarks - partially reverted move-ctor test update.
2 parents 6920fd0 + 8845e64 commit 8b5198f

35 files changed

+360
-43
lines changed

CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin")
88
# Add the subdirectories
99
add_subdirectory(CxxTestDesignPatternsUsingRTL)
1010
add_subdirectory(CxxRTLTypeRegistration)
11-
add_subdirectory(CxxRTLTestApplication)
11+
add_subdirectory(RTLTestRunApp)
12+
add_subdirectory(RTLBenchmarkApp)
1213
add_subdirectory(CxxTestProps)
1314
add_subdirectory(CxxTestUtils)
1415
add_subdirectory(ReflectionTemplateLib)

CxxRTLTestApplication/CMakeLists.txt

Lines changed: 0 additions & 38 deletions
This file was deleted.

MyReflection.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[{"function": "getMagnitude","namespace": "complex","functorId": [{"containerId": "35","index": "8","returnId": "46","hash_code": "358046","signature": "d (std::nullptr_t)"}]},{"function": "setImaginary","namespace": "complex","functorId": [{"containerId": "45","index": "1","returnId": "17","hash_code": "451017","signature": "void (d)"}]},{"function": "setReal","namespace": "complex","functorId": [{"containerId": "45","index": "0","returnId": "17","hash_code": "450017","signature": "void (d)"}]},{"function": "getComplexNumAsString","functorId": [{"containerId": "35","index": "7","returnId": "3","hash_code": "35703","signature": "std::string (std::nullptr_t)"}]},{"function": "reverseString","functorId": [{"containerId": "35","index": "6","returnId": "3","hash_code": "35603","signature": "std::string (std::nullptr_t)"}, {"containerId": "44","index": "0","returnId": "3","hash_code": "44003","signature": "std::string (std::string)"}, {"containerId": "36","index": "1","returnId": "3","hash_code": "36103","signature": "std::string (PKc)"}]},{"method": "reset","namespace": "nsdate","record": "Event","functorId": [{"containerId": "22","index": "2","recordId": "15","returnId": "17","hash_code": "2221517","signature": "void N6nsdate5EventE::(std::nullptr_t)"}]},{"method": "Event::Event()","namespace": "nsdate","record": "Event","functorId": [{"containerId": "18","index": "1","recordId": "15","returnId": "15","hash_code": "1811515","signature": "N6nsdate5EventE::(N3rtl5allocE)"}]},{"method": "getTheDate","namespace": "nsdate","record": "Calender","functorId": [{"containerId": "22","index": "6","recordId": "16","returnId": "14","hash_code": "2261614","signature": "N6nsdate4DateE N6nsdate8CalenderE::(std::nullptr_t)"}]},{"method": "getSavedDate","namespace": "nsdate","record": "Calender","functorId": [{"containerId": "22","index": "8","recordId": "16","returnId": "14","hash_code": "2281614","signature": "N6nsdate4DateE N6nsdate8CalenderE::(std::nullptr_t)"}]},{"method": "getTheEvent","namespace": "nsdate","record": "Calender","functorId": [{"containerId": "22","index": "5","recordId": "16","returnId": "15","hash_code": "2251615","signature": "N6nsdate5EventE N6nsdate8CalenderE::(std::nullptr_t)"}]},{"method": "getSavedEvent","namespace": "nsdate","record": "Calender","functorId": [{"containerId": "22","index": "7","recordId": "16","returnId": "15","hash_code": "2271615","signature": "N6nsdate5EventE N6nsdate8CalenderE::(std::nullptr_t)"}]},{"method": "create","namespace": "nsdate","record": "Calender","functorId": [{"containerId": "35","index": "4","recordId": "16","returnId": "16","hash_code": "3541616","signature": "N6nsdate8CalenderE (std::nullptr_t)"}]},{"method": "Calender::Calender()","namespace": "nsdate","record": "Calender","functorId": [{"containerId": "18","index": "8","recordId": "16","returnId": "16","hash_code": "1881616","signature": "N6nsdate8CalenderE::(N3rtl5allocE)"}]},{"method": "getAsString","namespace": "nsdate","record": "Date","functorId": [{"containerId": "28","index": "0","recordId": "14","returnId": "3","hash_code": "280143","signature": "std::string N6nsdate4DateE::(std::nullptr_t) const"}]},{"method": "updateDate","namespace": "nsdate","record": "Date","functorId": [{"containerId": "20","index": "3","recordId": "14","returnId": "17","hash_code": "2031417","signature": "void N6nsdate4DateE::(std::string)"}]},{"method": "Date::Date()","namespace": "nsdate","record": "Date","functorId": [{"containerId": "18","index": "2","recordId": "14","returnId": "14","hash_code": "1821414","signature": "N6nsdate4DateE::(N3rtl5allocE)"}, {"containerId": "25","index": "0","recordId": "14","returnId": "14","hash_code": "2501414","signature": "N6nsdate4DateE::(N3rtl5allocE, std::string)"}, {"containerId": "26","index": "0","recordId": "14","returnId": "14","hash_code": "2601414","signature": "N6nsdate4DateE::(N3rtl5allocE, j, j, j)"}]},{"method": "empty","namespace": "std","record": "string","functorId": [{"containerId": "28","index": "5","recordId": "3","returnId": "9","hash_code": "28539","signature": "b std::string::(std::nullptr_t) const"}]},{"method": "string::string()","namespace": "std","record": "string","functorId": [{"containerId": "18","index": "11","recordId": "3","returnId": "3","hash_code": "181133","signature": "std::string::(N3rtl5allocE)"}]},{"method": "empty","namespace": "std","record": "string_view","functorId": [{"containerId": "28","index": "6","recordId": "2","returnId": "9","hash_code": "28629","signature": "b St17basic_string_viewIcSt11char_traitsIcEE::(std::nullptr_t) const"}]},{"method": "string_view::string_view()","namespace": "std","record": "string_view","functorId": [{"containerId": "18","index": "12","recordId": "2","returnId": "2","hash_code": "181222","signature": "St17basic_string_viewIcSt11char_traitsIcEE::(N3rtl5allocE)"}]},{"method": "getProfile","record": "Person","functorId": [{"containerId": "35","index": "3","recordId": "11","returnId": "3","hash_code": "353113","signature": "std::string (std::nullptr_t)"}, {"containerId": "39","index": "0","recordId": "11","returnId": "3","hash_code": "390113","signature": "std::string (b)"}, {"containerId": "41","index": "0","recordId": "11","returnId": "3","hash_code": "410113","signature": "std::string (std::string, m)"}]},{"method": "createConst","record": "Person","functorId": [{"containerId": "35","index": "2","recordId": "11","returnId": "11","hash_code": "3521111","signature": "6Person (std::nullptr_t)"}]},{"method": "getDefaults","record": "Person","functorId": [{"containerId": "35","index": "1","recordId": "11","returnId": "3","hash_code": "351113","signature": "std::string (std::nullptr_t)"}]},{"method": "updateLastName","record": "Person","functorId": [{"containerId": "37","index": "0","recordId": "11","returnId": "17","hash_code": "3701117","signature": "void 6Person::(std::string) const"}]},{"method": "getFirstName","record": "Person","functorId": [{"containerId": "22","index": "4","recordId": "11","returnId": "3","hash_code": "224113","signature": "std::string 6Person::(std::nullptr_t)"}]},{"method": "updateAddress","record": "Person","functorId": [{"containerId": "22","index": "3","recordId": "11","returnId": "17","hash_code": "2231117","signature": "void 6Person::(std::nullptr_t)"}, {"containerId": "20","index": "5","recordId": "11","returnId": "17","hash_code": "2051117","signature": "void 6Person::(std::string)"}, {"containerId": "28","index": "2","recordId": "11","returnId": "17","hash_code": "2821117","signature": "void 6Person::(std::nullptr_t) const"}, {"containerId": "37","index": "1","recordId": "11","returnId": "17","hash_code": "3711117","signature": "void 6Person::(std::string) const"}]},{"method": "createPtr","record": "Person","functorId": [{"containerId": "35","index": "0","recordId": "11","returnId": "11","hash_code": "3501111","signature": "PK6Person (std::nullptr_t)"}]},{"method": "Person::Person()","record": "Person","functorId": [{"containerId": "18","index": "4","recordId": "11","returnId": "11","hash_code": "1841111","signature": "6Person::(N3rtl5allocE)"}, {"containerId": "25","index": "2","recordId": "11","returnId": "11","hash_code": "2521111","signature": "6Person::(N3rtl5allocE, std::string)"}]},{"method": "updateBookInfo","record": "Book","functorId": [{"containerId": "22","index": "1","recordId": "10","returnId": "17","hash_code": "2211017","signature": "void 4Book::(std::nullptr_t)"}, {"containerId": "23","index": "0","recordId": "10","returnId": "17","hash_code": "2301017","signature": "void 4Book::(PKc, d, std::string)"}, {"containerId": "24","index": "0","recordId": "10","returnId": "17","hash_code": "2401017","signature": "void 4Book::(std::string, d, PKc)"}]},{"method": "addCopyrightTag","record": "Book","functorId": [{"containerId": "20","index": "2","recordId": "10","returnId": "17","hash_code": "2021017","signature": "void 4Book::(std::string)"}]},{"method": "getPublishedOn","record": "Book","functorId": [{"containerId": "22","index": "0","recordId": "10","returnId": "3","hash_code": "220103","signature": "std::string 4Book::(std::nullptr_t)"}]},{"method": "setAuthor","record": "Book","functorId": [{"containerId": "20","index": "0","recordId": "10","returnId": "17","hash_code": "2001017","signature": "void 4Book::(std::string)"}]},{"method": "setDescription","record": "Book","functorId": [{"containerId": "20","index": "1","recordId": "10","returnId": "17","hash_code": "2011017","signature": "void 4Book::(std::string)"}]},{"method": "addPreface","record": "Book","functorId": [{"containerId": "21","index": "0","recordId": "10","returnId": "17","hash_code": "2101017","signature": "void 4Book::(std::string, const std::string&)"}]},{"method": "Book::Book()","record": "Book","functorId": [{"containerId": "18","index": "0","recordId": "10","returnId": "10","hash_code": "1801010","signature": "4Book::(N3rtl5allocE)"}, {"containerId": "19","index": "0","recordId": "10","returnId": "10","hash_code": "1901010","signature": "4Book::(N3rtl5allocE, d, std::string)"}]},{"method": "getBookByTitle","record": "Library","functorId": [{"containerId": "30","index": "1","recordId": "13","returnId": "10","hash_code": "3011310","signature": "4Book (const std::string&)"}]},{"method": "addBook","record": "Library","functorId": [{"containerId": "40","index": "0","recordId": "13","returnId": "17","hash_code": "4001317","signature": "void (4Book)"}]},{"method": "Library::Library()","record": "Library","functorId": [{"containerId": "18","index": "7","recordId": "13","returnId": "13","hash_code": "1871313","signature": "7Library::(N3rtl5allocE)"}]},{"method": "setAnimalName","record": "Animal","functorId": [{"containerId": "29","index": "0","recordId": "12","returnId": "17","hash_code": "2901217","signature": "void 6Animal::(const std::string&)"}, {"containerId": "31","index": "0","recordId": "12","returnId": "17","hash_code": "3101217","signature": "void 6Animal::(std::string&)"}, {"containerId": "32","index": "0","recordId": "12","returnId": "17","hash_code": "3201217","signature": "void 6Animal::(const std::string&&)"}]},{"method": "getFamilyName","record": "Animal","functorId": [{"containerId": "28","index": "1","recordId": "12","returnId": "3","hash_code": "281123","signature": "std::string 6Animal::(std::nullptr_t) const"}]},{"method": "updateZooKeeper","record": "Animal","functorId": [{"containerId": "30","index": "0","recordId": "12","returnId": "3","hash_code": "300123","signature": "std::string (const std::string&)"}, {"containerId": "33","index": "0","recordId": "12","returnId": "3","hash_code": "330123","signature": "std::string (std::string&)"}, {"containerId": "34","index": "0","recordId": "12","returnId": "3","hash_code": "340123","signature": "std::string (const std::string&&)"}]},{"method": "setFamilyName","record": "Animal","functorId": [{"containerId": "20","index": "4","recordId": "12","returnId": "17","hash_code": "2041217","signature": "void 6Animal::(std::string)"}]},{"method": "Animal::Animal()","record": "Animal","functorId": [{"containerId": "18","index": "3","recordId": "12","returnId": "12","hash_code": "1831212","signature": "6Animal::(N3rtl5allocE)"}, {"containerId": "25","index": "1","recordId": "12","returnId": "12","hash_code": "2511212","signature": "6Animal::(N3rtl5allocE, std::string)"}]},{"method": "char::char()","record": "char","functorId": [{"containerId": "18","index": "6","recordId": "1","returnId": "1","hash_code": "18611","signature": "c::(N3rtl5allocE)"}]},{"method": "void::void()","record": "void","functorId": [{"containerId": "18","index": "5","recordId": "17","returnId": "17","hash_code": "1851717","signature": "void::(N3rtl5allocE)"}]}]

RTLBenchmarkApp/CMakeLists.txt

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
cmake_minimum_required(VERSION 3.20)
2+
project(RTLBenchmarkApp LANGUAGES CXX)
3+
4+
set(CMAKE_CXX_STANDARD 20)
5+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
6+
7+
# ===============================
8+
# Dependencies (Google Benchmark)
9+
# ===============================
10+
include(FetchContent)
11+
12+
FetchContent_Declare(
13+
benchmark
14+
GIT_REPOSITORY https://github.com/google/benchmark.git
15+
GIT_TAG v1.8.3
16+
)
17+
18+
# Prevent benchmark from adding extra projects
19+
set(BENCHMARK_ENABLE_TESTING OFF CACHE BOOL "" FORCE)
20+
set(BENCHMARK_ENABLE_INSTALL OFF CACHE BOOL "" FORCE)
21+
22+
FetchContent_GetProperties(benchmark)
23+
if(NOT benchmark_POPULATED)
24+
FetchContent_Populate(benchmark)
25+
add_subdirectory(${benchmark_SOURCE_DIR} ${benchmark_BINARY_DIR} EXCLUDE_FROM_ALL)
26+
endif()
27+
28+
# ===============================
29+
# Common Include Paths
30+
# ===============================
31+
set(RTL_INCLUDE_DIRS
32+
inc
33+
"${CMAKE_SOURCE_DIR}/ReflectionTemplateLib/common"
34+
"${CMAKE_SOURCE_DIR}/ReflectionTemplateLib/detail/inc"
35+
"${CMAKE_SOURCE_DIR}/ReflectionTemplateLib/access/inc"
36+
"${CMAKE_SOURCE_DIR}/ReflectionTemplateLib/builder/inc"
37+
)
38+
39+
# ===============================
40+
# Test Executable
41+
# ===============================
42+
set(CXX_EXE_NAME RTLBenchmarkApp)
43+
44+
# ===============================
45+
# Benchmarks (only target)
46+
# ===============================
47+
add_executable(${CXX_EXE_NAME}
48+
src/main.cpp
49+
src/BenchMark.cpp # <-- added
50+
src/BenchMark.h # <-- optional (for IDE visibility)
51+
)
52+
53+
54+
target_include_directories(${CXX_EXE_NAME} PRIVATE ${RTL_INCLUDE_DIRS})
55+
56+
target_link_libraries(${CXX_EXE_NAME}
57+
PRIVATE
58+
benchmark
59+
ReflectionTemplateLib
60+
)

RTLBenchmarkApp/src/BenchMark.cpp

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
2+
#include <string>
3+
#include <optional>
4+
5+
#include "BenchMark.h"
6+
#include "RTLibInterface.h"
7+
8+
#if defined(_MSC_VER)
9+
# define NOINLINE __declspec(noinline)
10+
#elif defined(__GNUC__)
11+
# define NOINLINE __attribute__((noinline))
12+
#else
13+
# define NOINLINE
14+
#endif
15+
16+
17+
namespace {
18+
19+
static std::optional<std::string> g_msg;
20+
21+
NOINLINE static void sendMessage(const char* pMsg)
22+
{
23+
g_msg = pMsg;
24+
}
25+
26+
NOINLINE static std::string getMessage(const char* pMsg)
27+
{
28+
g_msg = pMsg;
29+
return std::string(pMsg);
30+
}
31+
32+
struct Node
33+
{
34+
NOINLINE void sendMessage(const char* pMsg)
35+
{
36+
g_msg = pMsg;
37+
}
38+
39+
NOINLINE std::string getMessage(const char* pMsg)
40+
{
41+
g_msg = pMsg;
42+
return std::string(pMsg);
43+
}
44+
};
45+
46+
const rtl::CxxMirror& cxx_mirror()
47+
{
48+
static auto m = rtl::CxxMirror({
49+
50+
rtl::type().record<Node>("node").build(),
51+
52+
rtl::type().function("sendMessage").build(sendMessage),
53+
54+
rtl::type().member<Node>().method("sendMessage").build(&Node::sendMessage),
55+
56+
rtl::type().function("getMessage").build(getMessage),
57+
58+
rtl::type().member<Node>().method("getMessage").build(&Node::getMessage)
59+
});
60+
return m;
61+
}
62+
}
63+
64+
65+
namespace rtl_bench
66+
{
67+
void BenchMark::directCall_noReturn(benchmark::State& state)
68+
{
69+
for (auto _ : state)
70+
{
71+
sendMessage("direct");
72+
benchmark::DoNotOptimize(g_msg);
73+
}
74+
}
75+
76+
77+
void BenchMark::lambdaCall_noReturn(benchmark::State& state)
78+
{
79+
std::function sendMsg = [](const char* pMsg) {
80+
sendMessage(pMsg);
81+
};
82+
83+
for (auto _ : state)
84+
{
85+
sendMsg("lambda");
86+
benchmark::DoNotOptimize(g_msg);
87+
}
88+
}
89+
90+
91+
void BenchMark::reflectedCall_noReturn(benchmark::State& state)
92+
{
93+
rtl::Function sendMsg = cxx_mirror().getFunction("sendMessage").value();
94+
for (auto _ : state)
95+
{
96+
benchmark::DoNotOptimize(sendMsg.bind<const char*>().call("reflected"));
97+
}
98+
}
99+
100+
101+
void BenchMark::reflectedMethodCall_noReturn(benchmark::State& state)
102+
{
103+
rtl::Record rNode = cxx_mirror().getRecord("node").value();
104+
rtl::Method sendMsg = rNode.getMethod("sendMessage").value();
105+
rtl::RObject robj = rNode.create<rtl::alloc::Stack>().second;
106+
107+
for (auto _ : state)
108+
{
109+
benchmark::DoNotOptimize(sendMsg.bind<const char*>(robj).call("reflected"));
110+
}
111+
}
112+
113+
114+
void BenchMark::directCall_withReturn(benchmark::State& state)
115+
{
116+
for (auto _ : state)
117+
{
118+
benchmark::DoNotOptimize(getMessage("direct"));
119+
}
120+
}
121+
122+
123+
void BenchMark::lambdaCall_withReturn(benchmark::State& state)
124+
{
125+
std::function getMsg = [](const char* pMsg) {
126+
return getMessage(pMsg);
127+
};
128+
129+
for (auto _ : state)
130+
{
131+
benchmark::DoNotOptimize(getMsg("lambda"));
132+
}
133+
}
134+
135+
136+
void BenchMark::reflectedCall_withReturn(benchmark::State& state)
137+
{
138+
rtl::Function getMsg = cxx_mirror().getFunction("getMessage").value();
139+
for (auto _ : state)
140+
{
141+
benchmark::DoNotOptimize(getMsg.bind<const char*>().call("reflected"));
142+
}
143+
}
144+
145+
146+
void BenchMark::reflectedMethodCall_withReturn(benchmark::State& state)
147+
{
148+
rtl::Record rNode = cxx_mirror().getRecord("node").value();
149+
rtl::Method getMsg = rNode.getMethod("getMessage").value();
150+
rtl::RObject robj = rNode.create<rtl::alloc::Stack>().second;
151+
152+
for (auto _ : state)
153+
{
154+
benchmark::DoNotOptimize(getMsg.bind<const char*>(robj).call("reflected"));
155+
}
156+
}
157+
}

RTLBenchmarkApp/src/BenchMark.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#pragma once
2+
3+
#include <benchmark/benchmark.h>
4+
5+
namespace rtl_bench
6+
{
7+
struct BenchMark
8+
{
9+
static void directCall_noReturn(benchmark::State& state);
10+
11+
static void lambdaCall_noReturn(benchmark::State& state);
12+
13+
static void reflectedCall_noReturn(benchmark::State& state);
14+
15+
static void reflectedMethodCall_noReturn(benchmark::State& state);
16+
17+
static void directCall_withReturn(benchmark::State& state);
18+
19+
static void lambdaCall_withReturn(benchmark::State& state);
20+
21+
static void reflectedCall_withReturn(benchmark::State& state);
22+
23+
static void reflectedMethodCall_withReturn(benchmark::State& state);
24+
};
25+
}

RTLBenchmarkApp/src/main.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
#include <string>
3+
#include <benchmark/benchmark.h>
4+
5+
#include "BenchMark.h"
6+
7+
// ------------------------------------------------------------
8+
// Register benchmarks
9+
// ------------------------------------------------------------
10+
11+
BENCHMARK(rtl_bench::BenchMark::directCall_noReturn);
12+
BENCHMARK(rtl_bench::BenchMark::lambdaCall_noReturn);
13+
BENCHMARK(rtl_bench::BenchMark::reflectedCall_noReturn);
14+
BENCHMARK(rtl_bench::BenchMark::reflectedMethodCall_noReturn);
15+
BENCHMARK(rtl_bench::BenchMark::directCall_withReturn);
16+
BENCHMARK(rtl_bench::BenchMark::lambdaCall_withReturn);
17+
BENCHMARK(rtl_bench::BenchMark::reflectedCall_withReturn);
18+
BENCHMARK(rtl_bench::BenchMark::reflectedMethodCall_withReturn);
19+
BENCHMARK_MAIN();

0 commit comments

Comments
 (0)