root/examples/string_conversions_performance.cpp

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. BOOST_AUTO_TEST_SUITE
  2. BOOST_AUTO_TEST_CASE_TEMPLATE

   1 /******************************************************************************
   2 ** $Header: svn+ssh://jmmcg@svn.code.sf.net/p/libjmmcg/code/trunk/libjmmcg/examples/string_conversions_performance.cpp 2345 2018-10-08 07:15:47Z jmmcg $
   3 **
   4 ** Copyright (c) 2017 by J.M.McGuiness, coder@hussar.me.uk
   5 **
   6 ** This library is free software; you can redistribute it and/or
   7 ** modify it under the terms of the GNU Lesser General Public
   8 ** License as published by the Free Software Foundation; either
   9 ** version 2.1 of the License, or (at your option) any later version.
  10 **
  11 ** This library is distributed in the hope that it will be useful,
  12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14 ** Lesser General Public License for more details.
  15 **
  16 ** You should have received a copy of the GNU Lesser General Public
  17 ** License along with this library; if not, write to the Free Software
  18 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19 */
  20 
  21 #include "stdafx.h"
  22 
  23 #include "core/stats_output.hpp"
  24 
  25 #define BOOST_TEST_MODULE libjmmcg_tests
  26 #include <boost/test/included/unit_test.hpp>
  27 
  28 #include <boost/test/test_case_template.hpp>
  29 #include <boost/mpl/list.hpp>
  30 
  31 #include "core/ave_deviation_meter.hpp"
  32 #include "core/ttypes.hpp"
  33 
  34 #include <boost/lexical_cast.hpp>
  35 
  36 // TODO #include <charconv>
  37 #include <chrono>
  38 
  39 using timed_results_t=jmmcg::ave_deviation_meter<unsigned long long>;
  40 
  41 ALIGN_TO_L1_CACHE static constexpr char const * const numbers[]={
  42         "572489496",
  43         "45643348",
  44         "51453335",
  45         "9978974234",
  46         "11447",
  47         "16836812",
  48         "15681223211",
  49         "125",
  50         "9845631699",
  51         "4598888",
  52         "0",
  53         "1",
  54         "1234567890123456789",
  55         "4581123500063313800"
  56 };
  57 
  58 struct std_atol {
  59         static long result(char const * const s, std::size_t) noexcept(true) {
  60                 assert(s);
  61                 return std::atol(s);
  62         }
  63 };
  64 
  65 struct std_strtol {
  66         static long result(char const * const s, std::size_t) noexcept(true) {
  67                 assert(s);
  68                 return std::strtol(s, nullptr, 10);
  69         }
  70 };
  71 /* TODO Not yet supported in g++ <=v7.2.0
  72 struct std_from_chars {
  73         static long result(char const * const s, std::size_t sz) noexcept(true) {
  74                 assert(s);
  75                 long res;
  76                 std::from_chars(s, s+sz, res, 10);
  77                 return res;
  78         }
  79 };
  80 
  81 struct std_to_chars {
  82         static std::size_t result(long v, char * const s, std::size_t sz) noexcept(true) {
  83                 assert(s);
  84                 std::to_chars(s, s+sz, v, 10);
  85                 return 42;
  86         }
  87 };
  88 */
  89 template<class V>
  90 struct jmmcg_from_string_baseline {
  91         static V result(char const * const s, std::size_t sz) noexcept(true) __attribute__((pure)) {
  92                 assert(s);
  93                 return jmmcg::fromstring<V>(s, sz);
  94         }
  95 };
  96 
  97 struct folly_ascii_to_int {
  98         static long result(char const * const s, std::size_t sz) noexcept(true) __attribute__((pure)) {
  99                 assert(s);
 100                 return jmmcg::folly_ascii_to_int(s, sz);
 101         }
 102 };
 103 
 104 template<class V>
 105 struct boost_lexical_cast_from {
 106         static V result(const char * const s, std::size_t) noexcept(true) __attribute__((pure)) {
 107                 assert(s);
 108                 return boost::lexical_cast<V>(s);
 109         }
 110 };
 111 
 112 struct folly_uint64ToBufferUnsafe {
 113         static std::size_t result(long v, char * const s, std::size_t sz) noexcept(true) __attribute__((pure)) {
 114                 assert(s);
 115                 return jmmcg::tostring(v, s, sz);
 116         }
 117 };
 118 
 119 typedef boost::mpl::list<
 120         folly_ascii_to_int,
 121         jmmcg_from_string_baseline<long>,
 122 // TODO jmmcg_from_string_baseline<double>,
 123         std_atol,
 124         boost_lexical_cast_from<long>,
 125         boost_lexical_cast_from<double>,
 126         std_strtol/* TODO Not yet supported in g++ <=v7.2.0
 127         std_from_chars*/
 128 > from_conversion_algorithms;
 129 
 130 typedef boost::mpl::list<
 131         folly_uint64ToBufferUnsafe/* TODO Not yet supported in g++ <=v7.2.0,
 132         std_to_chars*/
 133 > to_conversion_algorithms;
 134 
 135 BOOST_AUTO_TEST_SUITE(conversions_tests)
 136 
 137 BOOST_AUTO_TEST_SUITE(performance, *boost::unit_test::fixture<jmmcg::stats_to_csv::wrapper>(std::string("string_conversions_performance.csv")))
 138 
 139 /**
 140         \test <a href="./examples/string_conversions_performance.svg">Graph</a> of performance results for string-to-long conversion algorithms.
 141                         ==========================================================================================
 142         Test the performance of various string-to-long conversion algorithms.
 143 */
 144 BOOST_AUTO_TEST_CASE_TEMPLATE(from_string, algorithm, from_conversion_algorithms) {
 145 #ifdef JMMCG_PERFORMANCE_TESTS
 146         const unsigned long test_size=2<<21;
 147 #else
 148         const unsigned long test_size=2<<2;
 149 #endif
 150         const unsigned short loops_for_conv=200;
 151         const double perc_conv_estimate=5.0;
 152 
 153         unsigned long res=0;
 154 
 155         const std::pair<timed_results_t, bool> timed_results(jmmcg::compute_average_deviation<timed_results_t::value_type>(
 156                 perc_conv_estimate,
 157                 loops_for_conv,
 158                 [&res]() {
 159                         char const * const number=numbers[res%(sizeof(numbers)/sizeof(numbers[0]))];
 160                         const std::size_t sz=std::strlen(number);
 161                         const auto t1=std::chrono::high_resolution_clock::now();
 162                         for (unsigned long i=0; i<test_size; ++i) {
 163                                 res+=algorithm::result(number, sz);
 164                         }
 165                         const auto t2=std::chrono::high_resolution_clock::now();
 166                         return timed_results_t::value_type(static_cast<double>(test_size)*1000000/std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count());
 167                 }
 168         ));
 169         BOOST_CHECK_GT(res, 0);
 170         std::cout<<typeid(algorithm).name()<<" conversions/sec="<<timed_results.first<<std::endl;
 171 #ifdef JMMCG_PERFORMANCE_TESTS
 172         jmmcg::stats_to_csv::handle->stats<<timed_results.first.to_csv()<<std::flush;
 173         BOOST_CHECK(!timed_results.second);
 174 #endif
 175 }
 176 
 177 /**
 178         \test <a href="./examples/string_conversions_performance.svg">Graph</a> of performance results for long-to-string conversion algorithms.
 179                         ==========================================================================================
 180         Test the performance of various long-to-string conversion algorithms.
 181 */
 182 BOOST_AUTO_TEST_CASE_TEMPLATE(to_string, algorithm, to_conversion_algorithms) {
 183 #ifdef JMMCG_PERFORMANCE_TESTS
 184         const unsigned long test_size=2<<20;
 185 #else
 186         const unsigned long test_size=2<<2;
 187 #endif
 188         const unsigned short loops_for_conv=1000;
 189         const double perc_conv_estimate=5.0;
 190 
 191         std::size_t res=0;
 192 
 193         const std::pair<timed_results_t, bool> timed_results(jmmcg::compute_average_deviation<timed_results_t::value_type>(
 194                 perc_conv_estimate,
 195                 loops_for_conv,
 196                 [&res]() {
 197                         ALIGN_TO_L1_CACHE std::array<char, 512> buff={};
 198                         const auto t1=std::chrono::high_resolution_clock::now();
 199                         for (unsigned long i=0; i<test_size; ++i) {
 200                                 res+=algorithm::result(i, buff.begin(), buff.max_size());
 201                         }
 202                         const auto t2=std::chrono::high_resolution_clock::now();
 203                         return timed_results_t::value_type(static_cast<double>(test_size)*1000000/std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count());
 204                 }
 205         ));
 206         BOOST_CHECK_GT(res, 0);
 207         std::cout<<typeid(algorithm).name()<<" conversions/sec="<<timed_results.first<<std::endl;
 208 #ifdef JMMCG_PERFORMANCE_TESTS
 209         jmmcg::stats_to_csv::handle->stats<<timed_results.first.to_csv()<<std::flush;
 210         BOOST_CHECK(!timed_results.second);
 211 #endif
 212 }
 213 
 214 BOOST_AUTO_TEST_SUITE_END()
 215 
 216 BOOST_AUTO_TEST_SUITE_END()

/* [<][>][^][v][top][bottom][index][help] */