diff --git a/benchmark/from_chars_floating.cpp b/benchmark/from_chars_floating.cpp index 109a1b9..3a71c36 100644 --- a/benchmark/from_chars_floating.cpp +++ b/benchmark/from_chars_floating.cpp @@ -1,4 +1,5 @@ // Copyright 2023 Peter Dimov +// Copyright 2023 Matt Borland // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt @@ -13,6 +14,7 @@ #include #include #include +#include constexpr unsigned N = 2'000'000; constexpr int K = 10; @@ -40,6 +42,27 @@ template static BOOST_NOINLINE void init_input_data( std::vector +BOOST_NOINLINE void init_input_data( std::vector& data, bool general ) +{ + data.reserve(N / 10); + + std::random_device rd; + std::mt19937_64 rng(rd()); + std::uniform_real_distribution dist(0.0L, (std::numeric_limits::max)()); + + for( unsigned i = 0; i < N / 10; ++i ) + { + const long double x = dist(rng); + + char buffer[ 64 ]; + auto r = boost::charconv::to_chars( buffer, buffer + sizeof( buffer ), x, general? boost::charconv::chars_format::general : boost::charconv::chars_format::scientific ); + + std::string y( buffer, r.ptr ); + data.push_back( y ); + } +} + template static BOOST_NOINLINE void init_input_data_uint64( std::vector& data ) { data.reserve( N ); @@ -102,6 +125,26 @@ template<> BOOST_NOINLINE void test_strtox( std::vector con std::cout << " std::strtox, " << label << ": " << std::setw( 5 ) << ( t2 - t1 ) / 1ms << " ms (s=" << s << ")\n"; } +template<> BOOST_NOINLINE void test_strtox( std::vector const& data, bool, char const* label ) +{ + auto t1 = std::chrono::steady_clock::now(); + + long double s = 0; + + for( int i = 0; i < K; ++i ) + { + for( auto const& x: data ) + { + double y = std::strtold( x.c_str(), nullptr ); + s = s / 16.0L + y; + } + } + + auto t2 = std::chrono::steady_clock::now(); + + std::cout << " std::strtox, " << label << ": " << std::setw( 5 ) << ( t2 - t1 ) / 1ms << " ms (s=" << s << ")\n"; +} + template static BOOST_NOINLINE void test_std_from_chars( std::vector const& data, bool general, char const* label ) { auto t1 = std::chrono::steady_clock::now(); @@ -124,6 +167,28 @@ template static BOOST_NOINLINE void test_std_from_chars( std::vector() << ">, " << label << ": " << std::setw( 5 ) << ( t2 - t1 ) / 1ms << " ms (s=" << s << ")\n"; } +template<> BOOST_NOINLINE void test_std_from_chars( std::vector const& data, bool general, char const* label ) +{ + auto t1 = std::chrono::steady_clock::now(); + + long double s = 0; + + for( int i = 0; i < K; ++i ) + { + for( auto const& x: data ) + { + long double y; + std::from_chars( x.data(), x.data() + x.size(), y, general? std::chars_format::general: std::chars_format::scientific ); + + s = s / 16.0L + y; + } + } + + auto t2 = std::chrono::steady_clock::now(); + + std::cout << " std::from_chars, " << label << ": " << std::setw( 5 ) << ( t2 - t1 ) / 1ms << " ms (s=" << s << ")\n"; +} + template static BOOST_NOINLINE void test_boost_from_chars( std::vector const& data, bool general, char const* label ) { auto t1 = std::chrono::steady_clock::now(); @@ -146,6 +211,29 @@ template static BOOST_NOINLINE void test_boost_from_chars( std::vector< std::cout << "boost::charconv::from_chars<" << boost::core::type_name() << ">, " << label << ": " << std::setw( 5 ) << ( t2 - t1 ) / 1ms << " ms (s=" << s << ")\n"; } +template<> +BOOST_NOINLINE void test_boost_from_chars( std::vector const& data, bool general, char const* label ) +{ + auto t1 = std::chrono::steady_clock::now(); + + long double s = 0; + + for( int i = 0; i < K; ++i ) + { + for( auto const& x: data ) + { + long double y; + boost::charconv::from_chars( x.data(), x.data() + x.size(), y, general? boost::charconv::chars_format::general: boost::charconv::chars_format::scientific ); + + s = s / 16.0L + y; + } + } + + auto t2 = std::chrono::steady_clock::now(); + + std::cout << "boost::charconv::from_chars, " << label << ": " << std::setw( 5 ) << ( t2 - t1 ) / 1ms << " ms (s=" << s << ")\n"; +} + template static void test( bool general ) { std::vector data; @@ -182,9 +270,11 @@ int main() test( false ); test( false ); + test( false ); test( true ); test( true ); + test( true ); test2(); test2();