From 48c8145b4df599e9bb151c75238ce6dcb96c9613 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Mon, 25 Feb 2019 02:17:10 +0200 Subject: [PATCH] Add benchmark1.cpp --- benchmark/benchmark1.cpp | 161 +++++++++++++++++++++++++++++++++++++++ benchmark/benchmark1.md | 161 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 322 insertions(+) create mode 100644 benchmark/benchmark1.cpp create mode 100644 benchmark/benchmark1.md diff --git a/benchmark/benchmark1.cpp b/benchmark/benchmark1.cpp new file mode 100644 index 0000000..07cd5d0 --- /dev/null +++ b/benchmark/benchmark1.cpp @@ -0,0 +1,161 @@ +#if defined(ONLY_V2) +# define NO_BV +# define NO_SV +#endif + +#if defined(ONLY_BV) +# define NO_V2 +# define NO_SV +#endif + +#if defined(ONLY_SV) +# define NO_V2 +# define NO_BV +#endif + +#if !defined(NO_V2) +#include +#endif + +#if !defined(NO_BV) +#include +#endif + +#if !defined(NO_SV) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +template struct is_numeric: std::integral_constant::value || std::is_floating_point::value> +{ +}; + +template struct have_addition: std::integral_constant::value && is_numeric::value> +{ +}; + +template::value>> auto add( T const& t, U const& u ) +{ + return t + u; +} + +template::value>> double add( T const& /*t*/, U const& /*u*/ ) +{ + throw std::logic_error( "Invalid addition" ); +} + +inline double to_double( double const& v ) +{ + return v; +} + +#if !defined(NO_V2) + +template boost::variant2::variant operator+( boost::variant2::variant const& v1, boost::variant2::variant const& v2 ) +{ + return visit( [&]( auto const& x1, auto const & x2 ) -> boost::variant2::variant { return add( x1, x2 ); }, v1, v2 ); +} + +template double to_double( boost::variant2::variant const& v ) +{ + return boost::variant2::get( v ); +} + +#endif + +#if !defined(NO_BV) + +template boost::variant operator+( boost::variant const& v1, boost::variant const& v2 ) +{ + return boost::apply_visitor( [&]( auto const& x1, auto const & x2 ) -> boost::variant { return add( x1, x2 ); }, v1, v2 ); +} + +template double to_double( boost::variant const& v ) +{ + return boost::get( v ); +} + +#endif + +#if !defined(NO_SV) + +template std::variant operator+( std::variant const& v1, std::variant const& v2 ) +{ + return visit( [&]( auto const& x1, auto const & x2 ) -> std::variant { return add( x1, x2 ); }, v1, v2 ); +} + +template double to_double( std::variant const& v ) +{ + return std::get( v ); +} + +#endif + +template void test_( long long N ) +{ + std::vector w; + // lack of reserve is deliberate + + auto tp1 = std::chrono::high_resolution_clock::now(); + + for( long long i = 0; i < N; ++i ) + { + V v; + + if( i % 7 == 0 ) + { + v = i / 7; + } + else + { + v = i / 7.0; + } + + w.push_back( v ); + } + + V s = 0.0; + + for( long long i = 0; i < N; ++i ) + { + s = s + w[ i ]; + } + + auto tp2 = std::chrono::high_resolution_clock::now(); + + std::cout << std::setw( 6 ) << std::chrono::duration_cast( tp2 - tp1 ).count() << " ms; S=" << to_double( s ) << "\n"; +} + +template void test( long long N ) +{ + std::cout << "N=" << N << ":\n"; + + std::cout << " double: "; test_( N ); +#if !defined(NO_V2) + std::cout << " variant2: "; test_>( N ); +#endif +#if !defined(NO_BV) + std::cout << "boost::variant: "; test_>( N ); +#endif +#if !defined(NO_SV) + std::cout << " std::variant: "; test_>( N ); +#endif + + std::cout << '\n'; +} + +int main() +{ + long long const N = 100'000'000LL; + + test( N ); + test, std::map>( N ); +} diff --git a/benchmark/benchmark1.md b/benchmark/benchmark1.md new file mode 100644 index 0000000..a714c52 --- /dev/null +++ b/benchmark/benchmark1.md @@ -0,0 +1,161 @@ +# benchmark1.cpp results + +## VS 2017 15.9.7 64 bit (cl.exe 19.16, /std:c++17) + +### /Od + +#### Compile time + +``` + variant2 (-DONLY_V2): 1837 ms +boost::variant (-DONLY_BV): 2627 ms + std::variant (-DONLY_SV): 1425 ms +``` + +#### Run time + +``` +N=100000000: + double: 9041 ms; S=7.14286e+14 + variant2: 48367 ms; S=7.14286e+14 +boost::variant: 102776 ms; S=7.14286e+14 + std::variant: 40590 ms; S=7.14286e+14 + +N=100000000: + double: 9029 ms; S=7.14286e+14 + variant2: 92962 ms; S=7.14286e+14 +boost::variant: 110441 ms; S=7.14286e+14 + std::variant: 92974 ms; S=7.14286e+14 +``` + +### /O2 /NDEBUG + +#### Compile time + +``` + variant2 (-DONLY_V2): 2571 ms +boost::variant (-DONLY_BV): 3335 ms + std::variant (-DONLY_SV): 1903 ms +``` + +#### Run time + +``` +N=100000000: + double: 1949 ms; S=7.14286e+14 + variant2: 4176 ms; S=7.14286e+14 +boost::variant: 11312 ms; S=7.14286e+14 + std::variant: 4617 ms; S=7.14286e+14 + +N=100000000: + double: 1949 ms; S=7.14286e+14 + variant2: 11807 ms; S=7.14286e+14 +boost::variant: 15632 ms; S=7.14286e+14 + std::variant: 10725 ms; S=7.14286e+14 +``` + +## g++ 7.4.0 -std=c++17 (Cygwin 64 bit) + +### -O0 + +#### Compile time + +``` + variant2 (-DONLY_V2): 2734 ms +boost::variant (-DONLY_BV): 4308 ms + std::variant (-DONLY_SV): 2298 ms +``` + +#### Run time + +``` +N=100000000: + double: 3620 ms; S=7.14286e+14 + variant2: 29214 ms; S=7.14286e+14 +boost::variant: 88492 ms; S=7.14286e+14 + std::variant: 39510 ms; S=7.14286e+14 + +N=100000000: + double: 3642 ms; S=7.14286e+14 + variant2: 75822 ms; S=7.14286e+14 +boost::variant: 96680 ms; S=7.14286e+14 + std::variant: 66411 ms; S=7.14286e+14 +``` + +### -O1 + +#### Compile time + +``` + variant2 (-DONLY_V2): 2103 ms +boost::variant (-DONLY_BV): 3398 ms + std::variant (-DONLY_SV): 1841 ms +``` + +#### Run time + +``` +N=100000000: + double: 1576 ms; S=7.14286e+14 + variant2: 3424 ms; S=7.14286e+14 +boost::variant: 4356 ms; S=7.14286e+14 + std::variant: 3764 ms; S=7.14286e+14 + +N=100000000: + double: 1582 ms; S=7.14286e+14 + variant2: 9062 ms; S=7.14286e+14 +boost::variant: 9603 ms; S=7.14286e+14 + std::variant: 8825 ms; S=7.14286e+14 +``` + +### -O2 -DNDEBUG + +#### Compile time + +``` + variant2 (-DONLY_V2): 2276 ms +boost::variant (-DONLY_BV): 3647 ms + std::variant (-DONLY_SV): 2111 ms +``` + +#### Run time + +``` +N=100000000: + double: 1643 ms; S=7.14286e+14 + variant2: 3070 ms; S=7.14286e+14 +boost::variant: 3385 ms; S=7.14286e+14 + std::variant: 3880 ms; S=7.14286e+14 + +N=100000000: + double: 1622 ms; S=7.14286e+14 + variant2: 8101 ms; S=7.14286e+14 +boost::variant: 8611 ms; S=7.14286e+14 + std::variant: 8694 ms; S=7.14286e+14 +``` + +### -O3 -DNDEBUG + +#### Compile time + +``` + variant2 (-DONLY_V2): 2390 ms +boost::variant (-DONLY_BV): 3768 ms + std::variant (-DONLY_SV): 2094 ms +``` + +#### Run time + +``` +N=100000000: + double: 1611 ms; S=7.14286e+14 + variant2: 2975 ms; S=7.14286e+14 +boost::variant: 3232 ms; S=7.14286e+14 + std::variant: 3726 ms; S=7.14286e+14 + +N=100000000: + double: 1603 ms; S=7.14286e+14 + variant2: 8157 ms; S=7.14286e+14 +boost::variant: 8419 ms; S=7.14286e+14 + std::variant: 8659 ms; S=7.14286e+14 +```