On Tue, 18 Jul 2023 at 07:28, Ken Matsui via Libstdc++ < libstdc++@gcc.gnu.org> wrote: > I will eventually work on disjunction to somehow optimize, but in the > meantime, this might be a better implementation. Of course, my > benchmark could be wrong. > You should use __or_ internally in libstdc++ code, not std::disjunction. Patrick already optimized both of those, and __or_ is slightly faster (because it doesn't have to conform to the full requirements of std::disjunction). A compiler built-in for __or_ / __disjunction might perform better. But eventually if we're going to have built-ins for all of __is_arithmetic, __is_void, and __is_null_pointer, then we would want simply: __is_arithmetic(T) || __is_void(T) || __is_null_pointer(T) and so we wouldn't need to avoid instantiating any class templates at all. > > On Mon, Jul 17, 2023 at 11:24 PM Ken Matsui > wrote: > > > > Hi, > > > > I took a benchmark for this. > > > > > https://github.com/ken-matsui/gcc-benches/blob/main/is_fundamental-disjunction.md#mon-jul-17-105937-pm-pdt-2023 > > > > template > > struct is_fundamental > > : public std::bool_constant<__is_arithmetic(_Tp) > > || std::is_void<_Tp>::value > > || std::is_null_pointer<_Tp>::value> > > { }; > > > > is faster than: > > > > template > > struct is_fundamental > > : public std::bool_constant<__is_arithmetic(_Tp) > > || std::disjunction, > > std::is_null_pointer<_Tp> > > >::value> > > { }; > > > > Time: -32.2871% > > Peak Memory: -18.5071% > > Total Memory: -20.1991% > > > > Sincerely, > > Ken Matsui > > > > On Sun, Jul 16, 2023 at 9:49 PM Ken Matsui > wrote: > > > > > > On Sun, Jul 16, 2023 at 5:41 AM François Dumont > wrote: > > > > > > > > > > > > On 15/07/2023 06:55, Ken Matsui via Libstdc++ wrote: > > > > > This patch optimizes the performance of the is_fundamental trait by > > > > > dispatching to the new __is_arithmetic built-in trait. > > > > > > > > > > libstdc++-v3/ChangeLog: > > > > > > > > > > * include/std/type_traits (is_fundamental_v): Use > __is_arithmetic > > > > > built-in trait. > > > > > (is_fundamental): Likewise. Optimize the original > implementation. > > > > > > > > > > Signed-off-by: Ken Matsui > > > > > --- > > > > > libstdc++-v3/include/std/type_traits | 21 +++++++++++++++++---- > > > > > 1 file changed, 17 insertions(+), 4 deletions(-) > > > > > > > > > > diff --git a/libstdc++-v3/include/std/type_traits > b/libstdc++-v3/include/std/type_traits > > > > > index 7ebbe04c77b..cf24de2fcac 100644 > > > > > --- a/libstdc++-v3/include/std/type_traits > > > > > +++ b/libstdc++-v3/include/std/type_traits > > > > > @@ -668,11 +668,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > > > > #endif > > > > > > > > > > /// is_fundamental > > > > > +#if __has_builtin(__is_arithmetic) > > > > > + template > > > > > + struct is_fundamental > > > > > + : public __bool_constant<__is_arithmetic(_Tp) > > > > > + || is_void<_Tp>::value > > > > > + || is_null_pointer<_Tp>::value> > > > > > + { }; > > > > > > > > What about doing this ? > > > > > > > > template > > > > struct is_fundamental > > > > : public __bool_constant<__is_arithmetic(_Tp) > > > > || __or_, > > > > is_null_pointer<_Tp>>::value> > > > > { }; > > > > > > > > Based on your benches it seems that builtin __is_arithmetic is much > better that std::is_arithmetic. But __or_ could still avoid instantiation > of is_null_pointer. > > > > > > > Let me take a benchmark for this later. > >