Commit 3ba13c13 authored by neverlord's avatar neverlord

optimization

parent fdb4df86
...@@ -31,24 +31,41 @@ using std::endl; ...@@ -31,24 +31,41 @@ using std::endl;
using namespace cppa; using namespace cppa;
template<typename AbstractTuple> template<typename... T>
struct invoke_policy_helper struct dummy_tuple
{ {
size_t i; typedef void* ptr_type;
AbstractTuple& tup; typedef void const* const_ptr_type;
invoke_policy_helper(AbstractTuple& tp) : i(0), tup(tp) { }
template<typename T> ptr_type data[sizeof...(T) > 0 ? sizeof...(T) : 1];
void operator()(ge_mutable_reference_wrapper<T>& storage) inline const_ptr_type at(size_t p) const
{ {
storage = *reinterpret_cast<T*>(tup.mutable_at(i++)); return data[p];
} }
template<typename T> inline ptr_type mutable_at(size_t p)
void operator()(ge_mutable_reference_wrapper<const T>& storage)
{ {
storage = *reinterpret_cast<T const*>(tup.at(i++)); return const_cast<ptr_type>(data[p]);
}
void*& operator[](size_t p)
{
return data[p];
} }
}; };
template<size_t N, typename... Tn>
typename util::at<N, Tn...>::type const& get(dummy_tuple<Tn...> const& tv)
{
static_assert(N < sizeof...(Tn), "N >= tv.size()");
return *reinterpret_cast<typename util::at<N, Tn...>::type const*>(tv.at(N));
}
template<size_t N, typename... Tn>
typename util::at<N, Tn...>::type& get_ref(dummy_tuple<Tn...>& tv)
{
static_assert(N < sizeof...(Tn), "N >= tv.size()");
return *reinterpret_cast<typename util::at<N, Tn...>::type*>(tv.mutable_at(N));
}
template<typename T> template<typename T>
struct gref_wrapped struct gref_wrapped
{ {
...@@ -101,80 +118,85 @@ struct rm_all_refs ...@@ -101,80 +118,85 @@ struct rm_all_refs
template<wildcard_position, class Pattern, class FilteredPattern> template<wildcard_position, class Pattern, class FilteredPattern>
struct invoke_policy_impl; struct invoke_policy_impl;
template<class Pattern, class FilteredPattern> template<class Pattern, typename... Ts>
struct invoke_policy_impl<wildcard_position::nil, Pattern, FilteredPattern> struct invoke_policy_impl<wildcard_position::nil, Pattern, util::type_list<Ts...> >
{ {
typedef typename detail::tdata_from_type_list< typedef util::type_list<Ts...> filtered_pattern;
FilteredPattern
>::type
native_data_type;
typedef typename detail::static_types_array_from_type_list< typedef detail::tdata<Ts...> native_data_type;
FilteredPattern
>::type typedef typename detail::static_types_array<Ts...> arr_type;
arr_type;
enum shortcut_result
{
no_shortcut_available,
shortcut_failed,
shortcut_succeeded
};
template<class Target, class Tup> template<class Target, class Tup>
static inline bool shortcut(Target&, Tup&, bool&) static inline shortcut_result shortcut(Target&, Tup&)
{ {
return false; return no_shortcut_available;
} }
template<class Target, typename... T> template<class Target, typename... T>
static inline bool shortcut(Target& target, static inline shortcut_result shortcut(Target& target,
detail::tdata<T...> const& tup, detail::tdata<T...> const& tup,
bool& shortcut_result,
typename util::enable_if< typename util::enable_if<
util::tl_binary_forall< util::tl_binary_forall<
util::type_list< util::type_list<
typename rm_all_refs<T>::type... typename rm_all_refs<T>::type...
>, >,
FilteredPattern, filtered_pattern,
std::is_same std::is_same
> >
>::type* = 0) >::type* = 0)
{ {
shortcut_result = util::unchecked_apply_tuple<bool>(target, tup); if (util::unchecked_apply_tuple<bool>(target, tup))
return true; return shortcut_succeeded;
return shortcut_failed;
} }
template<class Target, typename... T> template<class Target, typename... T>
static inline bool shortcut(Target& target, static inline shortcut_result shortcut(Target& target,
detail::tdata<T...>& tup, detail::tdata<T...>& tup,
bool& shortcut_result,
typename util::enable_if< typename util::enable_if<
util::tl_binary_forall< util::tl_binary_forall<
util::type_list< util::type_list<
typename rm_all_refs<T>::type... typename rm_all_refs<T>::type...
>, >,
FilteredPattern, filtered_pattern,
std::is_same std::is_same
> >
>::type* = 0) >::type* = 0)
{ {
//static_assert(false, ""); if (util::unchecked_apply_tuple<bool>(target, tup))
shortcut_result = util::unchecked_apply_tuple<bool>(target, tup); return shortcut_succeeded;
return true; return shortcut_failed;
} }
template<class Target, typename NativeArg, typename Tuple> template<class Target, typename PtrType, typename Tuple, typename ValueIter>
static bool invoke(Target& target, static bool invoke(Target& target,
std::type_info const& arg_types, std::type_info const& arg_types,
detail::tuple_impl_info timpl, detail::tuple_impl_info timpl,
NativeArg* native_arg, PtrType* native_arg,
ValueIter vbegin,
ValueIter vend,
Tuple& tup) Tuple& tup)
{ {
bool shortcut_result = false; switch (shortcut(target, tup) )
if (shortcut(target, tup, shortcut_result))
{ {
return shortcut_result; case shortcut_succeeded: return true;
case shortcut_failed: return false;
default: ; // nop
} }
else if (arg_types == typeid(FilteredPattern)) if (arg_types == typeid(filtered_pattern))
{ {
if (native_arg) if (native_arg)
{ {
typedef typename util::if_else_c< typedef typename util::if_else_c<
std::is_const<NativeArg>::value, std::is_const<PtrType>::value,
native_data_type const*, native_data_type const*,
util::wrapped<native_data_type*> util::wrapped<native_data_type*>
>::type >::type
...@@ -187,11 +209,11 @@ struct invoke_policy_impl<wildcard_position::nil, Pattern, FilteredPattern> ...@@ -187,11 +209,11 @@ struct invoke_policy_impl<wildcard_position::nil, Pattern, FilteredPattern>
else if (timpl == detail::dynamically_typed) else if (timpl == detail::dynamically_typed)
{ {
auto& arr = arr_type::arr; auto& arr = arr_type::arr;
if (tup.size() != FilteredPattern::size) if (tup.size() != filtered_pattern::size)
{ {
return false; return false;
} }
for (size_t i = 0; i < FilteredPattern::size; ++i) for (size_t i = 0; i < filtered_pattern::size; ++i)
{ {
if (arr[i] != tup.type_at(i)) if (arr[i] != tup.type_at(i))
{ {
...@@ -205,34 +227,19 @@ struct invoke_policy_impl<wildcard_position::nil, Pattern, FilteredPattern> ...@@ -205,34 +227,19 @@ struct invoke_policy_impl<wildcard_position::nil, Pattern, FilteredPattern>
return false; return false;
} }
// either dynamically typed or statically typed but not a native tuple typedef dummy_tuple<PtrType*, Ts...> ttup_type;
typedef typename detail::tdata_from_type_list<
typename util::tl_map<
typename util::if_else<
std::is_const<Tuple>,
typename util::tl_map<Pattern, std::add_const>::type,
util::wrapped<Pattern>
>::type,
gref_mutable_wrapped
>::type
>::type
ttup_type;
ttup_type ttup; ttup_type ttup;
std::copy(vbegin, vend, std::begin(ttup.data));
// ... we restore it here again
typedef typename util::if_else< typedef typename util::if_else<
std::is_const<Tuple>, std::is_const<PtrType>,
ttup_type const&, ttup_type const&,
util::wrapped<ttup_type&> util::wrapped<ttup_type&>
>::type >::type
ttup_ref; ttup_ref;
//typename PolicyToken::wrapped_refs ttup; return util::unchecked_apply_tuple<bool>(target, static_cast<ttup_ref>(ttup));
invoke_policy_helper<Tuple> helper{tup};
util::static_foreach<0, FilteredPattern::size>::_ref(ttup, helper);
//return util::apply_tuple(target, ttup);
ttup_ref ttup_fwd = ttup;
return util::unchecked_apply_tuple<bool>(target, ttup_fwd);
} }
}; };
...@@ -241,56 +248,49 @@ struct invoke_policy_impl<wildcard_position::leading, ...@@ -241,56 +248,49 @@ struct invoke_policy_impl<wildcard_position::leading,
util::type_list<anything>, util::type_list<anything>,
util::type_list<> > util::type_list<> >
{ {
template<class Target, typename NativeArg, class Tuple> template<class Target, typename PtrType, class Tuple, typename ValueIter>
static bool invoke(Target& target, static bool invoke(Target& target,
std::type_info const&, std::type_info const&,
detail::tuple_impl_info, detail::tuple_impl_info,
NativeArg*, PtrType*,
ValueIter,
ValueIter,
Tuple&) Tuple&)
{ {
return target(); return target();
} }
}; };
template<class Pattern, class FilteredPattern> template<class Pattern, typename... Ts>
struct invoke_policy_impl<wildcard_position::trailing, Pattern, FilteredPattern> struct invoke_policy_impl<wildcard_position::trailing, Pattern, util::type_list<Ts...> >
{ {
template<class Target, typename NativeArg, class Tuple> typedef util::type_list<Ts...> filtered_pattern;
template<class Target, typename PtrType, class Tuple, typename ValueIter>
static bool invoke(Target& target, static bool invoke(Target& target,
std::type_info const&, std::type_info const&,
detail::tuple_impl_info, detail::tuple_impl_info,
NativeArg*, PtrType*,
ValueIter vbegin,
ValueIter,
Tuple& tup) Tuple& tup)
{ {
typedef typename detail::static_types_array_from_type_list< typedef detail::static_types_array<Ts...> arr_type;
FilteredPattern
>::type
arr_type;
auto& arr = arr_type::arr; auto& arr = arr_type::arr;
if (tup.size() < FilteredPattern::size) if (tup.size() < filtered_pattern::size)
{ {
return false; return false;
} }
for (size_t i = 0; i < FilteredPattern::size; ++i) for (size_t i = 0; i < filtered_pattern::size; ++i)
{ {
if (arr[i] != tup.type_at(i)) if (arr[i] != tup.type_at(i))
{ {
return false; return false;
} }
} }
typedef typename detail::tdata_from_type_list< typedef dummy_tuple<Ts...> ttup_type;
typename util::tl_map<
typename util::if_else<
std::is_const<Tuple>,
typename util::tl_map<FilteredPattern, std::add_const>::type,
util::wrapped<FilteredPattern>
>::type,
gref_mutable_wrapped
>::type
>::type
ttup_type;
ttup_type ttup; ttup_type ttup;
std::copy(vbegin, (vbegin + sizeof...(Ts)), std::begin(ttup.data));
typedef typename util::if_else< typedef typename util::if_else<
std::is_const<Tuple>, std::is_const<Tuple>,
...@@ -299,12 +299,7 @@ struct invoke_policy_impl<wildcard_position::trailing, Pattern, FilteredPattern> ...@@ -299,12 +299,7 @@ struct invoke_policy_impl<wildcard_position::trailing, Pattern, FilteredPattern>
>::type >::type
ttup_ref; ttup_ref;
//typename PolicyToken::wrapped_refs ttup; return util::unchecked_apply_tuple<bool>(target, static_cast<ttup_ref>(ttup));
invoke_policy_helper<Tuple> helper{tup};
util::static_foreach<0, FilteredPattern::size>::_ref(ttup, helper);
//return util::apply_tuple(target, ttup);
ttup_ref ttup_fwd = ttup;
return util::unchecked_apply_tuple<bool>(target, ttup_fwd);
} }
}; };
...@@ -674,12 +669,9 @@ struct invoke_helper ...@@ -674,12 +669,9 @@ struct invoke_helper
}; };
template<typename T> template<typename T>
struct is_manipulator_leaf; struct is_manipulator_leaf
template<typename First, typename Second>
struct is_manipulator_leaf<std::pair<First, Second> >
{ {
static constexpr bool value = Second::manipulates_args; static constexpr bool value = T::second_type::manipulates_args;
}; };
void collect_tdata(detail::tdata<>&) void collect_tdata(detail::tdata<>&)
...@@ -759,33 +751,55 @@ class projected_fun ...@@ -759,33 +751,55 @@ class projected_fun
projected_fun(projected_fun const&) = default; projected_fun(projected_fun const&) = default;
bool _invoke(any_tuple const& tup) const template<class Buffer, typename AbstractTuple, typename NativeDataPtr>
bool _do_invoke(Buffer& buf, AbstractTuple& vals, NativeDataPtr ndp) const
{ {
eval_order token; eval_order token;
invoke_helper<decltype(m_leaves)> fun{m_leaves}; invoke_helper<decltype(m_leaves)> fun{m_leaves};
auto& cvals = *(tup.cvals()); for (size_t i = 0; i < vals.size(); ++i)
buf.push_back(const_cast<void*>(vals.at(i)));
return util::static_foreach<0, eval_order::size> return util::static_foreach<0, eval_order::size>
::eval_or(token, ::eval_or(token,
fun, fun,
*(cvals.type_token()), *(vals.type_token()),
cvals.impl_type(), vals.impl_type(),
cvals.native_data(), ndp,
cvals); buf.begin(),
buf.end(),
vals);
}
bool _invoke(any_tuple const& tup) const
{
auto const& cvals = *(tup.cvals());
if (cvals.size() < 10)
{
util::fixed_vector<void*, 10> buf;
return _do_invoke(buf, cvals, cvals.native_data());
}
else
{
std::vector<void*> buf;
buf.reserve(cvals.size());
return _do_invoke(buf, cvals, cvals.native_data());
}
} }
bool _invoke(any_tuple& tup) const bool _invoke(any_tuple& tup) const
{ {
eval_order token;
invoke_helper<decltype(m_leaves)> fun{m_leaves};
tup.force_detach(); tup.force_detach();
auto& vals = *(tup.vals()); auto& vals = *(tup.vals());
return util::static_foreach<0, eval_order::size> if (vals.size() < 10)
::eval_or(token, {
fun, util::fixed_vector<void*, 10> buf;
*(vals.type_token()), return _do_invoke(buf, vals, vals.mutable_native_data());
vals.impl_type(), }
vals.mutable_native_data(), else
vals); {
std::vector<void*> buf;
buf.reserve(vals.size());
return _do_invoke(buf, vals, vals.mutable_native_data());
}
} }
bool invoke(any_tuple const& tup) const bool invoke(any_tuple const& tup) const
...@@ -830,6 +844,10 @@ class projected_fun ...@@ -830,6 +844,10 @@ class projected_fun
>::type >::type
ptr_type; ptr_type;
util::fixed_vector<void*, sizeof...(Args)> buf;
for (size_t i = 0; i < sizeof...(Args); ++i)
buf.push_back(const_cast<void*>(tup.at(i)));
eval_order token; eval_order token;
invoke_helper<decltype(m_leaves)> fun{m_leaves}; invoke_helper<decltype(m_leaves)> fun{m_leaves};
return util::static_foreach<0, eval_order::size> return util::static_foreach<0, eval_order::size>
...@@ -838,6 +856,8 @@ class projected_fun ...@@ -838,6 +856,8 @@ class projected_fun
typeid(util::type_list<typename util::rm_ref<Args>::type...>), typeid(util::type_list<typename util::rm_ref<Args>::type...>),
detail::statically_typed, detail::statically_typed,
static_cast<ptr_type>(nullptr), static_cast<ptr_type>(nullptr),
buf.begin(),
buf.end(),
static_cast<ref_type>(tup)); static_cast<ref_type>(tup));
} }
...@@ -1366,7 +1386,7 @@ size_t test__tuple() ...@@ -1366,7 +1386,7 @@ size_t test__tuple()
make_cow_tuple(1, 2, 3) make_cow_tuple(1, 2, 3)
}; };
constexpr size_t numInvokes = 100000000; constexpr size_t numInvokes = 1000000;
auto xvals = make_cow_tuple(1, 2, "3"); auto xvals = make_cow_tuple(1, 2, "3");
...@@ -1482,7 +1502,7 @@ size_t test__tuple() ...@@ -1482,7 +1502,7 @@ size_t test__tuple()
} }
} }
//exit(0); exit(0);
/* /*
VERBOSE(f00(42, 42)); VERBOSE(f00(42, 42));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment