sol2
sol2 copied to clipboard
[v4] 'Fastpass' for Usertypes
We are trying to introduce sol2 to a large codebase that would rely on a massive list of usertypes. However build times, compiler heap use and resulting binary sizes are all prohibitive.
Functions like sol::stack::check operate by resolving types through nested template instantiations. Would it be possible to reduce the overhead by introducing a 'fastpass' that would catch the common cases early?
I image something along the lines of this idea:
template <typename T, typename Handler>
bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
if constexpr (meta::meta_detail::is_adl_sol_lua_check_v<T>) {
return sol_lua_check(types<T>(), L, index, std::forward<Handler>(handler), tracking);
}
else {
using Tu = meta::unqualified_t<T>;
// Do all the checks for the common case right here and skip all the template resolution if possible.
if constexpr (
!(!std::is_reference_v<T> && is_unique_usertype_v<T>) && !(!std::is_reference_v<T> && is_container_v<T>) && !(!std::is_reference_v<T> && meta::is_specialization_of_v<T, nested>)
&& !(meta::meta_detail::is_adl_sol_lua_check_v<Tu>)
&& (lua_type_of_v<Tu> == type::userdata) && !(meta::any_same_v<Tu, userdata_value> || meta::is_specialization_of_v<Tu, basic_userdata>) && !(meta::is_specialization_of_v<Tu, user>) && !(std::is_pointer_v<Tu>) && !(meta::is_specialization_of_v<Tu, std::reference_wrapper>)
)
{
using detail_t = detail::as_value_tag<Tu>;
unqualified_checker<detail_t, lua_type_of_v<detail_t>> c;
// VC++ has a bad warning here: shut it up
(void)c;
return c.check(L, index, std::forward<Handler>(handler), tracking);
}
else
{
qualified_checker<T, lua_type_of_v<Tu>> c;
// VC++ has a bad warning here: shut it up
(void)c;
return c.check(L, index, std::forward<Handler>(handler), tracking);
}
}
}
Note the if constexpr to catch the common case and skip all the template resolution of the way to the as_value_tag.
Would this be feasible for all the functions involved in new_usertype calls? I image maintainability is a concern. However in the current state sol2 is sadly problematic for us.
We could move up the resolution here, yes. It would prevent a lot of instantiations for sol::stack::{unqualified}{checker,getter,setter} that happens. I think the only issue I'd have is, primarily, making the move in a way that would not disrupt folks relying on certain custom behaviors. I'll see how well I can pull something like this off.
I'll make sure to do something about this for v4, but uh. That's probably not gonna drop 'till next year!