Skip to content

Commit 67165ed

Browse files
authored
Benchmark setup refined.
- BM reveals RTL's true dispatch cost when zero workload. - BM setup steady, consistent across many multiple runs. - Enabled 'method(target)(args)' syntax parallel to 'method.bind(target).call(args)'
2 parents 10c9f74 + 1e9a370 commit 67165ed

32 files changed

+241
-173
lines changed

RTLBenchmarkApp/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ add_executable(${CXX_EXE_NAME}
5050
src/BenchMark.cpp
5151
src/StandardCall.h
5252
src/StandardCall.cpp
53+
src/StdFunction.cpp
5354
src/ReflectedCall.h
5455
src/ReflectedCall.cpp
5556
)

RTLBenchmarkApp/src/BenchMark.cpp

Lines changed: 46 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,74 @@
11

22

33
#include <optional>
4-
54
#include <iostream>
5+
#include <functional>
66

77
#include "BenchMark.h"
8+
#include "RTLibInterface.h"
89

9-
extern std::size_t g_work_load_scale;
10-
extern std::optional<std::string> g_work_done;
1110

12-
namespace
11+
namespace bm
1312
{
14-
NOINLINE static std::string work_load(bm::argStr_t& pMsg)
15-
{
16-
auto workStr = std::string();
17-
for(int i = 0; i < g_work_load_scale; ++i)
18-
{
19-
workStr += pMsg;
20-
}
21-
return workStr;
22-
}
13+
std::size_t g_work_load = 0;
14+
15+
std::optional<std::string> g_work_done = std::string();
16+
17+
extern std::string perform_work(const argStr_t& pMsg);
2318
}
2419

2520

2621
namespace bm
2722
{
28-
NOINLINE void sendMessage(argStr_t pMsg)
23+
void sendMessage(argStr_t pMsg)
2924
{
30-
volatile auto* p = &pMsg;
31-
static_cast<void>(p);
32-
33-
g_work_done = work_load(pMsg);
25+
if(g_work_load){
26+
g_work_done = perform_work(pMsg);
27+
}
3428
}
3529

36-
NOINLINE void Node::sendMessage(argStr_t pMsg)
30+
void Node::sendMessage(argStr_t pMsg)
3731
{
38-
volatile auto* p = &pMsg;
39-
static_cast<void>(p);
40-
41-
g_work_done = work_load(pMsg);
32+
if(g_work_load){
33+
g_work_done = perform_work(pMsg);
34+
}
4235
}
4336

44-
NOINLINE retStr_t getMessage(argStr_t pMsg)
37+
retStr_t getMessage(argStr_t pMsg)
4538
{
46-
volatile auto* p = &pMsg;
47-
static_cast<void>(p);
39+
if(g_work_load){
40+
g_work_done = perform_work(pMsg);
41+
}
42+
return retStr_t(g_work_done->c_str());
43+
}
4844

49-
g_work_done = work_load(pMsg);
50-
return bm::retStr_t(g_work_done->c_str());
45+
retStr_t Node::getMessage(argStr_t pMsg)
46+
{
47+
if(g_work_load){
48+
g_work_done = perform_work(pMsg);
49+
}
50+
return retStr_t(g_work_done->c_str());
5151
}
52+
}
5253

53-
NOINLINE retStr_t Node::getMessage(argStr_t pMsg)
54+
55+
namespace cxx
56+
{
57+
const rtl::CxxMirror& mirror()
5458
{
55-
volatile auto* p = &pMsg;
56-
static_cast<void>(p);
59+
static auto cxx_mirror = rtl::CxxMirror({
60+
61+
rtl::type().function("getMessage").build(bm::getMessage),
62+
63+
rtl::type().function("sendMessage").build(bm::sendMessage),
64+
65+
rtl::type().record<bm::Node>("Node").build(),
66+
67+
rtl::type().member<bm::Node>().method("sendMessage").build(&bm::Node::sendMessage),
68+
69+
rtl::type().member<bm::Node>().method("getMessage").build(&bm::Node::getMessage)
70+
});
5771

58-
g_work_done = work_load(pMsg);
59-
return bm::retStr_t(g_work_done->c_str());
72+
return cxx_mirror;
6073
}
6174
}

RTLBenchmarkApp/src/BenchMark.h

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,28 @@
11
#pragma once
22

3-
#include <benchmark/benchmark.h>
4-
5-
#include <optional>
63
#include <string>
74
#include <string_view>
85

9-
#if defined(_MSC_VER)
10-
# define NOINLINE __declspec(noinline)
11-
#elif defined(__GNUC__)
12-
# define NOINLINE __attribute__((noinline))
13-
#else
14-
# define NOINLINE
15-
#endif
16-
176
namespace bm
187
{
198
using argStr_t = std::string_view;
209
using retStr_t = std::string_view;
21-
22-
static const char* LONG_STR = "Lorem ipsum"
23-
"dolor sit amet, consectetur adipiscing elit, sed do"
24-
"do aeiusmod tempor incididunt uth labore et dolore magna aliqua. Ut enim ad minim veniam, quis"
25-
"nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure"
26-
"dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Except"
27-
"eur ssint occaecat cupidatat nnon proident, sunt in culpa qui officia deserunt mollit anim id"
28-
"Lorem ipsum dolor sit amet laboris nisi ut aliquip ex ea commodo";
2910

30-
static argStr_t g_longStr(LONG_STR);
31-
3211
struct Node
3312
{
3413
void sendMessage(argStr_t);
3514
retStr_t getMessage(argStr_t);
3615
};
16+
}
3717

38-
extern void sendMessage(argStr_t);
39-
extern retStr_t getMessage(argStr_t);
18+
19+
namespace bm
20+
{
21+
static argStr_t g_longStr = "Lorem ipsum"
22+
"dolor sit amet, consectetur adipiscing elit, sed do"
23+
"do aeiusmod tempor incididunt uth labore et dolore magna aliqua. Ut enim ad minim veniam, quis"
24+
"nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure"
25+
"dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Except"
26+
"eur ssint occaecat cupidatat nnon proident, sunt in culpa qui officia deserunt mollit anim id"
27+
"Lorem ipsum dolor sit amet laboris nisi ut aliquip ex ea commodo";
4028
}

RTLBenchmarkApp/src/ReflectedCall.cpp

Lines changed: 24 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,34 @@
11

2+
#include <benchmark/benchmark.h>
3+
24
#include "ReflectedCall.h"
35
#include "RTLibInterface.h"
6+
#include "BenchMark.h"
47

5-
namespace
8+
namespace cxx
69
{
7-
static const rtl::CxxMirror& cxx_mirror()
8-
{
9-
static auto m = rtl::CxxMirror({
10-
11-
rtl::type().function("getMessage").build(bm::getMessage),
12-
13-
rtl::type().function("sendMessage").build(bm::sendMessage),
14-
15-
rtl::type().record<bm::Node>("Node").build(),
10+
extern const rtl::CxxMirror& mirror();
11+
}
1612

17-
rtl::type().member<bm::Node>().method("sendMessage").build(&bm::Node::sendMessage),
13+
namespace
14+
{
15+
static rtl::Function GetMessage = cxx::mirror().getFunction("getMessage").value();
16+
static rtl::Function SendMessage = cxx::mirror().getFunction("sendMessage").value();
1817

19-
rtl::type().member<bm::Node>().method("getMessage").build(&bm::Node::getMessage)
20-
});
21-
return m;
22-
}
18+
static rtl::Method NodeGetMessage = cxx::mirror().getRecord("Node")->getMethod("getMessage").value();
19+
static rtl::Method NodeSendMessage = cxx::mirror().getRecord("Node")->getMethod("sendMessage").value();
2320

24-
static rtl::Record Node = cxx_mirror().getRecord("Node").value();
25-
26-
static rtl::RObject robj = Node.create<rtl::alloc::Stack>().rObject;
21+
static rtl::RObject nodeObj = []()
22+
{
23+
auto Node = cxx::mirror().getRecord("Node").value();
2724

28-
static rtl::Method NodeGetMessage = Node.getMethod("getMessage").value();
25+
rtl::RObject robj = Node.create<rtl::alloc::Stack>().rObject;
2926

30-
static rtl::Method NodeSendMessage = Node.getMethod("sendMessage").value();
31-
32-
static rtl::Function GetMessage = cxx_mirror().getFunction("getMessage").value();
33-
34-
static rtl::Function SendMessage = cxx_mirror().getFunction("sendMessage").value();
27+
return std::move(robj);
28+
}();
3529
}
3630

3731

38-
3932
namespace
4033
{
4134
static auto _test0 = []()
@@ -50,7 +43,7 @@ namespace
5043

5144
static auto _test1 = []()
5245
{
53-
auto err = NodeSendMessage(robj)(bm::g_longStr).err;
46+
auto err = NodeSendMessage(nodeObj)(bm::g_longStr).err;
5447

5548
if (err != rtl::error::None) {
5649
std::cout << "[1] error: " << rtl::to_string(err) << "\n";
@@ -70,7 +63,7 @@ namespace
7063

7164
static auto _test3 = []()
7265
{
73-
auto err = NodeGetMessage(robj)(bm::g_longStr).err;
66+
auto err = NodeGetMessage(nodeObj)(bm::g_longStr).err;
7467

7568
if (err != rtl::error::None) {
7669
std::cout << "[3] error: " << rtl::to_string(err) << "\n";
@@ -86,7 +79,7 @@ void ReflectedCall::noReturn(benchmark::State& state)
8679
static auto _=_test0();
8780
for (auto _: state) {
8881

89-
auto error = SendMessage.bind().call(bm::g_longStr).err;
82+
auto error = SendMessage(bm::g_longStr).err;
9083
benchmark::DoNotOptimize(error);
9184
}
9285
}
@@ -97,7 +90,7 @@ void ReflectedCall::withReturn(benchmark::State& state)
9790
static auto _=_test2();
9891
for (auto _: state)
9992
{
100-
auto error = GetMessage.bind().call(bm::g_longStr).err;
93+
auto error = GetMessage(bm::g_longStr).err;
10194
benchmark::DoNotOptimize(error);
10295
}
10396
}
@@ -108,7 +101,7 @@ void ReflectedMethodCall::noReturn(benchmark::State& state)
108101
static auto _=_test1();
109102
for (auto _: state)
110103
{
111-
auto error = NodeSendMessage.bind(robj).call(bm::g_longStr).err;
104+
auto error = NodeSendMessage(nodeObj)(bm::g_longStr).err;
112105
benchmark::DoNotOptimize(error);
113106
}
114107
}
@@ -119,7 +112,7 @@ void ReflectedMethodCall::withReturn(benchmark::State& state)
119112
static auto _=_test3();
120113
for (auto _: state)
121114
{
122-
auto error = NodeGetMessage.bind(robj).call(bm::g_longStr).err;
115+
auto error = NodeGetMessage(nodeObj)(bm::g_longStr).err;
123116
benchmark::DoNotOptimize(error);
124117
}
125118
}

RTLBenchmarkApp/src/ReflectedCall.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#pragma once
22

3-
#include "BenchMark.h"
3+
#include <benchmark/benchmark.h>
44

55
struct ReflectedCall
66
{

0 commit comments

Comments
 (0)