Skip to content

Commit 1249e4f

Browse files
committed
Improved benchmark.
1 parent 03fed0e commit 1249e4f

File tree

1 file changed

+116
-26
lines changed

1 file changed

+116
-26
lines changed

tests/benchmark/b7_callbacklist_vs_function_list.cpp

+116-26
Original file line numberDiff line numberDiff line change
@@ -17,45 +17,88 @@
1717
#include <functional>
1818
#include <vector>
1919

20-
// To enable benchmark, change below line to #if 1
21-
#if 1
22-
2320
namespace {
2421

22+
#if defined(_MSC_VER)
23+
#define NON_INLINE __declspec(noinline)
24+
#else
25+
// gcc
26+
#define NON_INLINE __attribute__((noinline))
27+
#endif
28+
29+
volatile int globalValue = 0;
30+
31+
void globalFunction(int a, const int b)
32+
{
33+
globalValue += a + b;
34+
}
35+
36+
NON_INLINE void nonInlineGlobalFunction(int a, const int b)
37+
{
38+
globalValue += a + b;
39+
}
40+
41+
struct FunctionObject
42+
{
43+
void operator() (int a, const int b)
44+
{
45+
globalValue += a + b;
46+
}
47+
48+
virtual void virFunc(int a, const int b)
49+
{
50+
globalValue += a + b;
51+
}
52+
53+
void nonVirFunc(int a, const int b)
54+
{
55+
globalValue += a + b;
56+
}
57+
58+
NON_INLINE virtual void nonInlineVirFunc(int a, const int b)
59+
{
60+
globalValue += a + b;
61+
}
62+
63+
NON_INLINE void nonInlineNonVirFunc(int a, const int b)
64+
{
65+
globalValue += a + b;
66+
}
67+
};
68+
#undef NON_INLINE
69+
2570
template <typename Policies>
26-
void doCallbackListVsFunctionList(const std::string & message)
71+
using CLT = eventpp::CallbackList<void (int, int), Policies>;
72+
using FLT = std::vector<std::function<void (int, int)> >;
73+
74+
template <typename Policies, typename AddCL, typename AddFL>
75+
void doCallbackListVsFunctionList(const std::string & message, AddCL && addCl, AddFL && addFL)
2776
{
28-
eventpp::CallbackList<void (size_t), Policies> callbackList;
29-
std::vector<std::function<void (size_t)> > functionList;
30-
constexpr size_t callbackCount = 100;
31-
constexpr size_t iterateCount = 1000 * 1000;
32-
volatile size_t data = 0;
77+
CLT<Policies> callbackList;
78+
FLT functionList;
79+
constexpr int callbackCount = 100;
80+
constexpr int iterateCount = 1000 * 1000;
3381

34-
for(size_t i = 0; i < callbackCount; ++i) {
35-
callbackList.append([&data, i](size_t index) {
36-
data += i + index;
37-
});
38-
functionList.push_back([&data, i](size_t index) {
39-
data += i + index;
40-
});
82+
for(int i = 0; i < callbackCount; ++i) {
83+
addCl(callbackList);
84+
addFL(functionList);
4185
}
4286
const uint64_t timeCallbackList = measureElapsedTime(
4387
[iterateCount, &callbackList]() {
44-
for(size_t iterate = 0; iterate < iterateCount; ++iterate) {
45-
callbackList(iterate);
88+
for(int iterate = 0; iterate < iterateCount; ++iterate) {
89+
callbackList(iterate, iterate);
4690
}
4791
}
4892
);
4993
const uint64_t timeFunctionList = measureElapsedTime(
5094
[iterateCount, &functionList]() {
51-
for(size_t iterate = 0; iterate < iterateCount; ++iterate) {
95+
for(int iterate = 0; iterate < iterateCount; ++iterate) {
5296
for(auto & func : functionList) {
53-
func(iterate);
97+
func(iterate, iterate);
5498
}
5599
}
56100
}
57101
);
58-
REQUIRE(data >= 0);
59102

60103
std::cout << message << " timeCallbackList " << timeCallbackList << std::endl;
61104
std::cout << message << " timeFunctionList " << timeFunctionList << std::endl;
@@ -68,13 +111,60 @@ TEST_CASE("b7, CallbackList vs vector of functions")
68111
struct PoliciesMultiThreading {
69112
using Threading = eventpp::MultipleThreading;
70113
};
71-
doCallbackListVsFunctionList<PoliciesMultiThreading>("Multi thread");
72-
73114
struct PoliciesSingleThreading {
74115
using Threading = eventpp::SingleThreading;
75116
};
76-
doCallbackListVsFunctionList<PoliciesSingleThreading>("Single thread");
77-
}
117+
118+
struct BenchmarkItem {
119+
std::string message;
120+
std::function<void (CLT<PoliciesMultiThreading> &)> addClMulti;
121+
std::function<void (CLT<PoliciesSingleThreading> &)> addClSingle;
122+
std::function<void (FLT &)> addFl;
123+
};
124+
std::vector<BenchmarkItem> itemList {
125+
{
126+
"global",
127+
[](CLT<PoliciesMultiThreading> & cl) {
128+
cl.append(&globalFunction);
129+
},
130+
[](CLT<PoliciesSingleThreading> & cl) {
131+
cl.append(&globalFunction);
132+
},
133+
[](FLT & fl) {
134+
fl.push_back(&globalFunction);
135+
}
136+
},
78137

138+
{
139+
"nonInlineGlobalFunction",
140+
[](CLT<PoliciesMultiThreading> & cl) {
141+
cl.append(&nonInlineGlobalFunction);
142+
},
143+
[](CLT<PoliciesSingleThreading> & cl) {
144+
cl.append(&nonInlineGlobalFunction);
145+
},
146+
[](FLT & fl) {
147+
fl.push_back(&nonInlineGlobalFunction);
148+
}
149+
},
79150

80-
#endif
151+
{
152+
"FunctionObject",
153+
[](CLT<PoliciesMultiThreading> & cl) {
154+
cl.append(FunctionObject());
155+
},
156+
[](CLT<PoliciesSingleThreading> & cl) {
157+
cl.append(FunctionObject());
158+
},
159+
[](FLT & fl) {
160+
fl.push_back(FunctionObject());
161+
}
162+
},
163+
164+
};
165+
166+
for(BenchmarkItem & item : itemList) {
167+
doCallbackListVsFunctionList<PoliciesMultiThreading>("Multi thread, " + item.message, item.addClMulti, item.addFl);
168+
}
169+
170+
}

0 commit comments

Comments
 (0)