On Thu, Aug 31, 2023 at 6:57 AM Ken Matsui <kmat...@cs.washington.edu> wrote: > > On Tue, Aug 8, 2023 at 1:19 PM Jonathan Wakely <jwak...@redhat.com> wrote: > > > > > > > > On Tue, 18 Jul 2023 at 07:25, Ken Matsui via Libstdc++ > > <libstd...@gcc.gnu.org> 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<typename _Tp> > >> 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<typename _Tp> > >> struct is_fundamental > >> : public std::bool_constant<__is_arithmetic(_Tp) > >> || std::disjunction<std::is_void<_Tp>, > >> std::is_null_pointer<_Tp> > >> >::value> > >> { }; > >> > >> Time: -32.2871% > >> Peak Memory: -18.5071% > >> Total Memory: -20.1991% > > > > > > But what about the fallback implementation of is_fundamental where we don't > > have the __is_arithmetic built-in? > > That fallback implementation would be this: > https://github.com/ken-matsui/gsoc23/blob/967e20770599f2a8925c9794669111faef11beb7/is_fundamental.cc#L11-L15. > > The is_fundamental-disjunction.cc benchmark used the USE_BUILTIN > macro, but in this benchmark, I used it to just switch two different > implementations that use the __is_arithmetic built-in. > > > - : public __or_<is_arithmetic<_Tp>, is_void<_Tp>, > > - is_null_pointer<_Tp>>::type > > + : public __bool_constant<is_arithmetic<_Tp>::value > > + || is_void<_Tp>::value > > + || is_null_pointer<_Tp>::value> > > > > Here the use of __or_ means that for is_fundamental<int> we don't > > instantiate is_void<int> and is_null_pointer<int>. Isn't that still > > worthwhile? > > > Let me take a benchmark with __or_ later! We may see a difference. > Here is the benchmark result with __or_:
https://github.com/ken-matsui/gsoc23/blob/main/is_fundamental-disjunction.md#thu-aug-31-075127-am-pdt-2023 Time: -23.3935% Peak Memory: -10.2915% Total Memory: -14.4165% Considering the following was with disjunction, __or_ is faster than disjunction, but still just || seems much faster. 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 <kmat...@cs.washington.edu> > >> wrote: > >> > > >> > On Sun, Jul 16, 2023 at 5:41 AM François Dumont <frs.dum...@gmail.com> > >> > 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 <kmat...@gcc.gnu.org> > >> > > > --- > >> > > > 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<typename _Tp> > >> > > > + struct is_fundamental > >> > > > + : public __bool_constant<__is_arithmetic(_Tp) > >> > > > + || is_void<_Tp>::value > >> > > > + || is_null_pointer<_Tp>::value> > >> > > > + { }; > >> > > > >> > > What about doing this ? > >> > > > >> > > template<typename _Tp> > >> > > struct is_fundamental > >> > > : public __bool_constant<__is_arithmetic(_Tp) > >> > > || __or_<is_void<_Tp>, > >> > > 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. > >>