11
2+ #include < any>
23#include < optional>
34
4- #include " BenchMark.h"
5- #include " RTLibInterface.h"
6-
7- #if defined(_MSC_VER)
8- # define NOINLINE __declspec (noinline)
9- #elif defined(__GNUC__)
10- # define NOINLINE __attribute__ ((noinline))
11- #else
12- # define NOINLINE
13- #endif
14-
15- static const std::string LONG_STR =
16- " Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "
17- " Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. "
18- " Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. "
19- " Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." ;
20-
21- namespace {
22-
23- static std::optional<std::string> g_msg;
5+ #include < iostream>
246
25- NOINLINE static void sendMessage (const char * pMsg)
26- {
27- g_msg = pMsg;
28- }
29-
30- NOINLINE static std::string getMessage (const char * pMsg)
31- {
32- g_msg = pMsg;
33- return std::string (pMsg);
34- }
35-
36- struct Node
37- {
38- NOINLINE void sendMessage (const char * pMsg)
39- {
40- g_msg = pMsg;
41- }
7+ #include " BenchMark.h"
428
43- NOINLINE std::string getMessage (const char * pMsg)
44- {
45- g_msg = pMsg;
46- return std::string (pMsg);
47- }
48- };
499
50- const rtl::CxxMirror& cxx_mirror ()
51- {
52- static auto m = rtl::CxxMirror ({
10+ namespace {
5311
54- rtl::type ().record <Node>(" node" ).build (),
12+ static const char * LONG_STR = " Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do"
13+ " do aeiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis"
14+ " nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure"
15+ " dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Except"
16+ " eur ssint occaecat cupidatat nnon proident, sunt in culpa qui officia deserunt mollit anim id" ;
5517
56- rtl::type ().function (" sendMessage" ).build (sendMessage),
18+ // Pre-created string to isolate call overhead
19+ static const std::string g_longStr (LONG_STR);
20+ }
5721
58- rtl::type ().member <Node>().method (" sendMessage" ).build (&Node::sendMessage),
5922
60- rtl::type ().function (" getMessage" ).build (getMessage),
23+ namespace rtl_bench
24+ {
25+ void BenchMark::directCall_noReturn (benchmark::State& state)
26+ {
27+ for (auto _ : state)
28+ {
29+ sendMessage (g_longStr);
30+ benchmark::DoNotOptimize (g_msg);
31+ }
32+ }
33+
34+
35+ void BenchMark::autoLambdaCall_noReturn (benchmark::State& state)
36+ {
37+ auto sendMsg = [](const str_type& pMsg) {
38+ sendMessage (pMsg);
39+ };
40+
41+ for (auto _ : state)
42+ {
43+ sendMsg (g_longStr);
44+ benchmark::DoNotOptimize (g_msg);
45+ }
46+ }
47+
48+
49+ void BenchMark::stdFunctionCall_noReturn (benchmark::State& state)
50+ {
51+ static std::function sendMsg = [](const str_type& pMsg) {
52+ sendMessage (pMsg);
53+ };
54+
55+ for (auto _ : state)
56+ {
57+ sendMsg (g_longStr);
58+ benchmark::DoNotOptimize (g_msg);
59+ }
60+ }
61+
62+ void BenchMark::directCall_withReturn (benchmark::State& state)
63+ {
64+ static auto _ = []() {
65+ std::cout << " --------------------------------------------------"
66+ " ---------------------------------------------" << std::endl;
67+ return 0 ;
68+ }();
69+
70+ for (auto _ : state)
71+ {
72+ benchmark::DoNotOptimize (getMessage (g_longStr));
73+ }
74+ }
75+
76+
77+ void BenchMark::autoLambdaCall_withReturn (benchmark::State& state)
78+ {
79+ auto getMsg = [](const str_type& pMsg) {
80+ return getMessage (pMsg);
81+ };
82+
83+ for (auto _ : state)
84+ {
85+ benchmark::DoNotOptimize (getMsg (g_longStr));
86+ }
87+ }
88+
89+
90+ void BenchMark::stdFunctionCall_withReturn (benchmark::State& state)
91+ {
92+ static std::function getMsg = [](const str_type& pMsg) {
93+ return getMessage (pMsg);
94+ };
95+
96+ for (auto _ : state)
97+ {
98+ benchmark::DoNotOptimize (getMsg (g_longStr));
99+ }
100+ }
61101
62- rtl::type ().member <Node>().method (" getMessage" ).build (&Node::getMessage)
63- });
64- return m;
65- }
66102}
67103
68104
69- namespace rtl_bench
105+ namespace rtl_bench
70106{
71- void BenchMark::directCall_noReturn (benchmark::State& state)
72- {
73- for (auto _ : state)
74- {
75- sendMessage (LONG_STR.c_str ());
76- benchmark::DoNotOptimize (g_msg);
77- }
78- }
79-
80-
81- void BenchMark::lambdaCall_noReturn (benchmark::State& state)
82- {
83- static std::function sendMsg = [](const char * pMsg) {
84- sendMessage (pMsg);
85- };
86-
87- for (auto _ : state)
88- {
89- sendMsg (LONG_STR.c_str ());
90- benchmark::DoNotOptimize (g_msg);
91- }
92- }
93-
94-
95- void BenchMark::reflectedCall_noReturn (benchmark::State& state)
96- {
97- static rtl::Function sendMsg = cxx_mirror ().getFunction (" sendMessage" ).value ();
98- for (auto _ : state)
99- {
100- benchmark::DoNotOptimize (sendMsg.bind ().call (LONG_STR.c_str ()));
101- }
102- }
103-
104-
105- void BenchMark::reflectedMethodCall_noReturn (benchmark::State& state)
106- {
107- static rtl::Record rNode = cxx_mirror ().getRecord (" node" ).value ();
108- static rtl::Method sendMsg = rNode.getMethod (" sendMessage" ).value ();
109- static rtl::RObject robj = rNode.create <rtl::alloc::Stack>().rObject ;
110-
111- for (auto _ : state)
112- {
113- benchmark::DoNotOptimize (sendMsg.bind (robj).call (LONG_STR.c_str ()));
114- }
115- }
116-
117-
118- void BenchMark::directCall_withReturn (benchmark::State& state)
119- {
120- for (auto _ : state)
121- {
122- benchmark::DoNotOptimize (getMessage (LONG_STR.c_str ()));
123- }
124- }
125-
126-
127- void BenchMark::lambdaCall_withReturn (benchmark::State& state)
128- {
129- static std::function getMsg = [](const char * pMsg) {
130- return getMessage (pMsg);
131- };
132-
133- for (auto _ : state)
134- {
135- benchmark::DoNotOptimize (getMsg (LONG_STR.c_str ()));
136- }
137- }
138-
139-
140- void BenchMark::reflectedCall_withReturn (benchmark::State& state)
141- {
142- static rtl::Function getMsg = cxx_mirror ().getFunction (" getMessage" ).value ();
143- for (auto _ : state)
144- {
145- benchmark::DoNotOptimize (getMsg.bind ().call (LONG_STR.c_str ()));
146- }
147- }
148-
149-
150- void BenchMark::reflectedMethodCall_withReturn (benchmark::State& state)
151- {
152- static rtl::Record rNode = cxx_mirror ().getRecord (" node" ).value ();
153- static rtl::Method getMsg = rNode.getMethod (" getMessage" ).value ();
154- static rtl::RObject robj = rNode.create <rtl::alloc::Stack>().rObject ;
155-
156- for (auto _ : state)
157- {
158- benchmark::DoNotOptimize (getMsg.bind (robj).call (LONG_STR.c_str ()));
159- }
160- }
161- }
107+ void BenchMark::reflectedCall_noReturn (benchmark::State& state)
108+ {
109+ static rtl::Function sendMsg = cxx_mirror ().getFunction (" sendMessage" ).value ();
110+
111+ static auto _ = []() {
112+ if (sendMsg.bind <str_type>().call (g_longStr).err == rtl::error::None) {
113+ std::cout << " [rtl:0] call success.\n " ;
114+ }
115+ else {
116+ std::cout << " [rtl:0] call failed.\n " ;
117+ }
118+ return 0 ;
119+ }();
120+
121+ for (auto _ : state)
122+ {
123+ benchmark::DoNotOptimize (sendMsg.bind <str_type>().call (g_longStr));
124+ }
125+ }
126+
127+
128+ void BenchMark::reflectedMethodCall_noReturn (benchmark::State& state)
129+ {
130+ static rtl::Record rNode = cxx_mirror ().getRecord (" Node" ).value ();
131+ static rtl::Method sendMsg = rNode.getMethod (" sendMessage" ).value ();
132+ static rtl::RObject robj = rNode.create <rtl::alloc::Stack>().rObject ;
133+ static auto _ = []() {
134+ if (sendMsg.bind <str_type>(robj).call (g_longStr).err == rtl::error::None) {
135+ std::cout << " [rtl:1] call success.\n " ;
136+ }
137+ else {
138+ std::cout << " [rtl:1] call failed.\n " ;
139+ }
140+ return 0 ;
141+ }();
142+
143+ for (auto _ : state)
144+ {
145+ benchmark::DoNotOptimize (sendMsg.bind <str_type>(robj).call (g_longStr));
146+ }
147+ }
148+
149+
150+ void BenchMark::reflectedCall_withReturn (benchmark::State& state)
151+ {
152+ static rtl::Function getMsg = cxx_mirror ().getFunction (" getMessage" ).value ();
153+ static auto _ = []() {
154+ if (getMsg.bind <str_type>().call (g_longStr).err == rtl::error::None) {
155+ std::cout << " [rtl:2] call success.\n " ;
156+ }
157+ else {
158+ std::cout << " [rtl:2] call failed.\n " ;
159+ }
160+ return 0 ;
161+ }();
162+
163+ for (auto _ : state)
164+ {
165+ benchmark::DoNotOptimize (getMsg.bind <str_type>().call (g_longStr));
166+ }
167+ }
168+
169+
170+ void BenchMark::reflectedMethodCall_withReturn (benchmark::State& state)
171+ {
172+ static rtl::Record rNode = cxx_mirror ().getRecord (" Node" ).value ();
173+ static rtl::Method getMsg = rNode.getMethod (" getMessage" ).value ();
174+ static rtl::RObject robj = rNode.create <rtl::alloc::Stack>().rObject ;
175+ static auto _ = []() {
176+ if (getMsg.bind <str_type>(robj).call (g_longStr).err == rtl::error::None) {
177+ std::cout << " [rtl:3] call success.\n " ;
178+ }
179+ else {
180+ std::cout << " [rtl:3] call failed.\n " ;
181+ }
182+ return 0 ;
183+ }();
184+
185+ for (auto _ : state)
186+ {
187+ benchmark::DoNotOptimize (getMsg.bind <str_type>(robj).call (g_longStr));
188+ }
189+ }
190+ }
0 commit comments