Skip to content

Commit a8d9e51

Browse files
committed
Performance centric refactor.
1 parent 95e8160 commit a8d9e51

File tree

13 files changed

+108
-80
lines changed

13 files changed

+108
-80
lines changed

RTLBenchmarkApp/src/BenchMark.cpp

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11

2-
#include <string>
32
#include <optional>
43

54
#include "BenchMark.h"
@@ -13,6 +12,11 @@
1312
# define NOINLINE
1413
#endif
1514

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.";
1620

1721
namespace {
1822

@@ -33,7 +37,7 @@ namespace {
3337
{
3438
NOINLINE void sendMessage(const char* pMsg)
3539
{
36-
g_msg = pMsg;
40+
g_msg = pMsg;
3741
}
3842

3943
NOINLINE std::string getMessage(const char* pMsg)
@@ -68,7 +72,7 @@ namespace rtl_bench
6872
{
6973
for (auto _ : state)
7074
{
71-
sendMessage("direct");
75+
sendMessage(LONG_STR.c_str());
7276
benchmark::DoNotOptimize(g_msg);
7377
}
7478
}
@@ -82,7 +86,7 @@ namespace rtl_bench
8286

8387
for (auto _ : state)
8488
{
85-
sendMsg("lambda");
89+
sendMsg(LONG_STR.c_str());
8690
benchmark::DoNotOptimize(g_msg);
8791
}
8892
}
@@ -91,10 +95,9 @@ namespace rtl_bench
9195
void BenchMark::reflectedCall_noReturn(benchmark::State& state)
9296
{
9397
static rtl::Function sendMsg = cxx_mirror().getFunction("sendMessage").value();
94-
static auto sendMsgCall = sendMsg.bind<const char*>();
9598
for (auto _ : state)
9699
{
97-
benchmark::DoNotOptimize(sendMsgCall.call("reflected"));
100+
benchmark::DoNotOptimize(sendMsg.bind().call(LONG_STR.c_str()));
98101
}
99102
}
100103

@@ -107,7 +110,7 @@ namespace rtl_bench
107110

108111
for (auto _ : state)
109112
{
110-
benchmark::DoNotOptimize(sendMsg.bind<const char*>(robj).call("reflected"));
113+
benchmark::DoNotOptimize(sendMsg.bind(robj).call(LONG_STR.c_str()));
111114
}
112115
}
113116

@@ -116,7 +119,7 @@ namespace rtl_bench
116119
{
117120
for (auto _ : state)
118121
{
119-
benchmark::DoNotOptimize(getMessage("direct"));
122+
benchmark::DoNotOptimize(getMessage(LONG_STR.c_str()));
120123
}
121124
}
122125

@@ -129,7 +132,7 @@ namespace rtl_bench
129132

130133
for (auto _ : state)
131134
{
132-
benchmark::DoNotOptimize(getMsg("lambda"));
135+
benchmark::DoNotOptimize(getMsg(LONG_STR.c_str()));
133136
}
134137
}
135138

@@ -139,7 +142,7 @@ namespace rtl_bench
139142
static rtl::Function getMsg = cxx_mirror().getFunction("getMessage").value();
140143
for (auto _ : state)
141144
{
142-
benchmark::DoNotOptimize(getMsg.bind<const char*>().call("reflected"));
145+
benchmark::DoNotOptimize(getMsg.bind().call(LONG_STR.c_str()));
143146
}
144147
}
145148

@@ -152,7 +155,7 @@ namespace rtl_bench
152155

153156
for (auto _ : state)
154157
{
155-
benchmark::DoNotOptimize(getMsg.bind<const char*>(robj).call("reflected"));
158+
benchmark::DoNotOptimize(getMsg.bind(robj).call(LONG_STR.c_str()));
156159
}
157160
}
158161
}

ReflectionTemplateLib/access/inc/Function.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ namespace rtl {
6767
Function(const Function& pOther, const detail::FunctorId& pFunctorId,
6868
const std::string_view pFunctorName);
6969

70-
std::size_t hasSignatureId(const std::size_t pSignatureId) const;
70+
const std::size_t hasSignatureId(const std::size_t pSignatureId) const;
7171

7272
GETTER(detail::methodQ, Qualifier, m_qualifier);
7373

ReflectionTemplateLib/access/inc/Function.hpp

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,38 +22,38 @@ namespace rtl
2222
return detail::FunctionCaller<_signature...>(*this);
2323
}
2424

25-
/* @method: hasSignature<...>()
26-
@param: set of arguments, explicitly specified as template parameter.
27-
@return: bool, if the functor associated with this object is of certain signature or not.
28-
* a single 'Function' object can be associated with multiple overloads of same function.
29-
* the set of arguments passed is checked agains all registered overloads, returns true if matched with any one.
30-
*/ template<class ..._args>
25+
/* @method: hasSignature<...>()
26+
@param: set of arguments, explicitly specified as template parameter.
27+
@return: bool, if the functor associated with this object is of certain signature or not.
28+
* a single 'Function' object can be associated with multiple overloads of same function.
29+
* the set of arguments passed is checked agains all registered overloads, returns true if matched with any one.
30+
*/ template<class ..._args>
3131
inline bool Function::hasSignature() const
3232
{
3333
//hasSignatureId() returns the index of the 'lambda' in functor-container, which cannot be '-1'.
3434
return (hasSignatureId(detail::FunctorContainer<_args...>::getContainerId()) != -1);
3535
}
3636

3737

38-
/* @method: operator()()
39-
@param: variadic arguments.
40-
@return: Return, possible error & return value of from the reflected call.
41-
* if the arguments did not match with any overload, returns RObject with error::SignatureMismatch
42-
* providing optional syntax, Function::call() does the exact same thing.
43-
*/ template<class ..._args>
38+
/* @method: operator()()
39+
@param: variadic arguments.
40+
@return: Return, possible error & return value of from the reflected call.
41+
* if the arguments did not match with any overload, returns RObject with error::SignatureMismatch
42+
* providing optional syntax, Function::call() does the exact same thing.
43+
*/ template<class ..._args>
4444
inline Return Function::operator()(_args&& ...params) const noexcept
4545
{
4646
return bind().call(std::forward<_args>(params)...);
4747
}
4848

4949

50-
/* @method: hasSignatureId()
51-
@param: const std::size_t& (signatureId to be found)
52-
@return: the index of the functor in the functor-table.
53-
* a 'Function' object may be associated with multiple functors in case of overloads.
54-
* every overload will have unique 'FunctorId', contained by one 'Function' object.
55-
* given signatureId is compared against the signatureId of all overloads registered.
56-
*/ inline std::size_t Function::hasSignatureId(const std::size_t pSignatureId) const
50+
/* @method: hasSignatureId()
51+
@param: const std::size_t& (signatureId to be found)
52+
@return: the index of the functor in the functor-table.
53+
* a 'Function' object may be associated with multiple functors in case of overloads.
54+
* every overload will have unique 'FunctorId', contained by one 'Function' object.
55+
* given signatureId is compared against the signatureId of all overloads registered.
56+
*/ inline const std::size_t Function::hasSignatureId(const std::size_t pSignatureId) const
5757
{
5858
//simple linear-search, efficient for small set of elements.
5959
for (const auto& functorId : m_functorIds) {

ReflectionTemplateLib/common/Constants.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ namespace rtl::detail
131131
NonConst // Non-const instance method
132132
};
133133

134+
constexpr const std::string_view NAMESPACE_GLOBAL = "global";
134135

135136
inline static const std::string ctor_name(const std::string_view pRecordName = "") {
136137
// [critical] Must not change. Constructors are identified using this format.
@@ -157,5 +158,11 @@ namespace rtl::detail
157158
return _var; \
158159
}
159160

160-
constexpr const std::string_view NAMESPACE_GLOBAL = "global";
161+
#if defined(_MSC_VER)
162+
#define FORCE_INLINE __forceinline
163+
#elif defined(__GNUC__) || defined(__clang__)
164+
#define FORCE_INLINE inline __attribute__((always_inline))
165+
#else
166+
#define FORCE_INLINE inline
167+
#endif
161168
}

ReflectionTemplateLib/common/rtl_traits.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ namespace rtl
7070
{
7171
using value_type = std::nullptr_t;
7272
static constexpr const auto type = detail::Wrapper::None;
73-
static auto id() { return detail::TypeId<>::None; }
73+
static constexpr std::size_t id() { return detail::TypeId<>::None; }
7474
};
7575

7676

@@ -79,7 +79,7 @@ namespace rtl
7979
{
8080
using value_type = T;
8181
static constexpr const auto type = detail::Wrapper::Shared;
82-
static auto id() { return detail::TypeId<std::shared_ptr<T>>::get(); }
82+
static constexpr std::size_t id() { return detail::TypeId<std::shared_ptr<T>>::get(); }
8383
};
8484

8585

@@ -88,7 +88,7 @@ namespace rtl
8888
{
8989
using value_type = T;
9090
static constexpr const auto type = detail::Wrapper::Unique;
91-
static auto id() { return detail::TypeId<std::unique_ptr<T>>::get(); }
91+
static constexpr std::size_t id() { return detail::TypeId<std::unique_ptr<T>>::get(); }
9292
};
9393

9494

@@ -97,7 +97,7 @@ namespace rtl
9797
{
9898
using value_type = T;
9999
static constexpr const auto type = detail::Wrapper::Weak;
100-
static auto id() { return detail::TypeId<std::weak_ptr<T>>::get(); }
100+
static constexpr std::size_t id() { return detail::TypeId<std::weak_ptr<T>>::get(); }
101101
};
102102

103103
template<typename T>

ReflectionTemplateLib/detail/inc/FunctionCaller.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,6 @@ namespace rtl::detail
3636
if (index != rtl::index_none) {
3737
return Container::template forwardCall<_args...>(index, std::forward<_args>(params)...);
3838
}
39-
return { error::SignatureMismatch, RObject{ } };
39+
return { error::SignatureMismatch, RObject{} };
4040
}
4141
}

ReflectionTemplateLib/detail/inc/RObjectBuilder.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ namespace rtl::detail
3737

3838
static const std::size_t rtlManagedInstanceCount();
3939

40-
template <class T, rtl::alloc _allocOn>
41-
static RObject build(T&& pVal, const bool pIsConstCastSafe);
40+
template <class T, rtl::alloc _allocOn, bool _isConstCastSafe>
41+
static RObject build(T&& pVal);
4242
};
4343
}
4444

@@ -55,10 +55,10 @@ namespace rtl
5555
inline RObject reflect(T(&pArr)[N])
5656
{
5757
if constexpr (std::is_same_v<traits::raw_t<T>, char>) {
58-
return detail::RObjectBuilder::build<std::string_view, alloc::Stack>(std::string_view(pArr, N - 1), !traits::is_const_v<T>);
58+
return detail::RObjectBuilder::build<std::string_view, alloc::Stack, !traits::is_const_v<T>>(std::string_view(pArr, N - 1));
5959
}
6060
else {
61-
return detail::RObjectBuilder::build<std::vector<T>, alloc::Stack>(std::vector(pArr, pArr + N), !traits::is_const_v<T>);
61+
return detail::RObjectBuilder::build<std::vector<T>, alloc::Stack, !traits::is_const_v<T>>(std::vector(pArr, pArr + N));
6262
}
6363
}
6464

@@ -69,12 +69,12 @@ namespace rtl
6969
using _T = traits::raw_t<T>;
7070
if constexpr (traits::std_wrapper<_T>::type == detail::Wrapper::None)
7171
{
72-
return detail::RObjectBuilder::build<T, alloc::Stack>(std::forward<T>(pVal), !traits::is_const_v<T>);
72+
return detail::RObjectBuilder::build<T, alloc::Stack, !traits::is_const_v<T>>(std::forward<T>(pVal));
7373
}
7474
else
7575
{
7676
constexpr bool isConstCastSafe = !traits::is_const_v<typename traits::std_wrapper<_T>::value_type>;
77-
return detail::RObjectBuilder::build<T, alloc::Stack>(std::forward<T>(pVal), isConstCastSafe);
77+
return detail::RObjectBuilder::build<T, alloc::Stack, isConstCastSafe>(std::forward<T>(pVal));
7878
}
7979
}
8080
}

ReflectionTemplateLib/detail/inc/RObjectBuilder.hpp

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,13 @@ namespace rtl::detail {
4949
{
5050
case alloc::Stack:
5151
return { error::None,
52-
RObjectBuilder::template build<_T, alloc::Stack>(_T(srcObj), true) };
52+
RObjectBuilder::template build<_T, alloc::Stack, true>(_T(srcObj))
53+
};
5354

5455
case alloc::Heap:
5556
return { error::None,
56-
RObjectBuilder::template build<_T*, alloc::Heap>(new _T(srcObj), true) };
57+
RObjectBuilder::template build<_T*, alloc::Heap, true>(new _T(srcObj))
58+
};
5759

5860
default:
5961
return { error::EmptyRObject, RObject{} };
@@ -72,26 +74,31 @@ namespace rtl::detail {
7274

7375

7476

75-
template<class T, rtl::alloc _allocOn>
76-
inline RObject RObjectBuilder::build(T&& pVal, const bool pIsConstCastSafe)
77+
template<class T, rtl::alloc _allocOn, bool _isConstCastSafe>
78+
inline RObject RObjectBuilder::build(T&& pVal)
7779
{
7880
using _T = traits::raw_t<T>;
7981
constexpr bool isRawPointer = std::is_pointer_v<traits::remove_const_n_ref_t<T>>;
8082

8183
if constexpr (_allocOn == alloc::Heap)
8284
{
8385
static_assert(isRawPointer, "Invalid 'alloc' specified for non-pointer-type 'T'");
84-
return RObject(RObjectId::create<std::unique_ptr<_T>, _allocOn>(pIsConstCastSafe),
85-
std::any(RObjectUPtr<_T>(std::unique_ptr<_T>(static_cast<_T*>(pVal)))),
86+
return RObject(RObjectId::create<std::unique_ptr<_T>, _allocOn, _isConstCastSafe>(),
87+
std::any {
88+
std::in_place_type<RObjectUPtr<_T>>,
89+
RObjectUPtr<_T>(std::unique_ptr<_T>(static_cast<_T*>(pVal)))
90+
},
8691
buildCloner<_T>(),
8792
getConverters<std::unique_ptr<_T>>());
8893
}
8994
else if constexpr (_allocOn == alloc::Stack)
9095
{
9196
if constexpr (isRawPointer)
9297
{
93-
return RObject(RObjectId::create<T, _allocOn>(pIsConstCastSafe),
94-
std::any(static_cast<const _T*>(pVal)),
98+
return RObject(RObjectId::create<T, _allocOn, _isConstCastSafe>(),
99+
std::any {
100+
static_cast<const _T*>(pVal)
101+
},
95102
buildCloner<_T>(),
96103
getConverters<T>());
97104
}
@@ -100,16 +107,22 @@ namespace rtl::detail {
100107
if constexpr (traits::std_wrapper<_T>::type == Wrapper::Unique)
101108
{
102109
using U = traits::std_wrapper<_T>::value_type;
103-
return RObject(RObjectId::create<T, _allocOn>(pIsConstCastSafe),
104-
std::any(RObjectUPtr<U>(std::move(pVal))),
110+
return RObject(RObjectId::create<T, _allocOn, _isConstCastSafe>(),
111+
std::any {
112+
std::in_place_type<RObjectUPtr<U>>,
113+
RObjectUPtr<U>(std::move(pVal))
114+
},
105115
buildCloner<_T>(),
106116
getConverters<T>());
107117
}
108-
else
118+
else
109119
{
110120
static_assert(std::is_copy_constructible_v<_T>, "T must be copy-constructible (std::any requires this).");
111-
return RObject(RObjectId::create<T, _allocOn>(pIsConstCastSafe),
112-
std::any(std::forward<T>(pVal)),
121+
return RObject(RObjectId::create<T, _allocOn, _isConstCastSafe>(),
122+
std::any {
123+
std::in_place_type<T>,
124+
std::forward<T>(pVal)
125+
},
113126
buildCloner<_T>(),
114127
getConverters<T>());
115128
}

ReflectionTemplateLib/detail/inc/RObjectId.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ namespace rtl::detail
3737
GETTER(EntityKind, ContainedAs, m_containsAs)
3838

3939
template<class T>
40-
static constexpr EntityKind getEntityKind()
40+
FORCE_INLINE static constexpr EntityKind getEntityKind()
4141
{
4242
using W = traits::std_wrapper<traits::raw_t<T>>;
4343
using _T = traits::raw_t<std::conditional_t<(W::type == Wrapper::None), T, typename W::value_type>>;
@@ -56,8 +56,8 @@ namespace rtl::detail
5656
}
5757

5858

59-
template<class T, rtl::alloc _allocOn>
60-
static RObjectId create(bool pIsConstCastSafe)
59+
template<class T, rtl::alloc _allocOn, bool _isConstCastSafe>
60+
FORCE_INLINE static RObjectId create()
6161
{
6262
// extract wrapper info.
6363
using _W = traits::std_wrapper<traits::raw_t<T>>;
@@ -67,8 +67,8 @@ namespace rtl::detail
6767

6868
const std::size_t wrapperId = _W::id();
6969
const std::size_t typeId = rtl::detail::TypeId<_T>::get();
70-
const bool isWrappingConst = (_W::type != Wrapper::None && traits::is_const_v<typename _W::value_type>);
71-
return RObjectId{ isWrappingConst, pIsConstCastSafe, typeId, wrapperId, _allocOn, _W::type, entityKind };
70+
constexpr bool isWrappingConst = (_W::type != Wrapper::None && traits::is_const_v<typename _W::value_type>);
71+
return RObjectId{ isWrappingConst, _isConstCastSafe, typeId, wrapperId, _allocOn, _W::type, entityKind };
7272
}
7373
};
7474
}

0 commit comments

Comments
 (0)