Mercurial > hg > orthanc-stone
changeset 1181:bf08d28bc652
Added timing tests
author | Benjamin Golinvaux <bgo@osimis.io> |
---|---|
date | Wed, 20 Nov 2019 20:25:23 +0100 |
parents | f68da12e852b |
children | 3076a8a66db5 |
files | UnitTestsSources/GenericToolboxTests.cpp |
diffstat | 1 files changed, 222 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/UnitTestsSources/GenericToolboxTests.cpp Wed Nov 20 10:47:42 2019 +0100 +++ b/UnitTestsSources/GenericToolboxTests.cpp Wed Nov 20 20:25:23 2019 +0100 @@ -20,10 +20,15 @@ #include <Framework/Toolbox/GenericToolbox.h> +#include <boost/chrono.hpp> +#include <boost/lexical_cast.hpp> + #include "gtest/gtest.h" #include "stdint.h" +#include <cmath> + TEST(GenericToolbox, TestLegitDoubleString) { using OrthancStone::GenericToolbox::LegitDoubleString; @@ -3840,6 +3845,112 @@ } } +static const size_t NUM_TIMINGS_CONVS = 2000; + + +//4444444444444444$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + +TEST(GenericToolbox, TestStringToDoubleHardNeg_lexical_cast_vs_StringToDouble) +{ + using OrthancStone::GenericToolbox::StringToDouble; + const double TOLERANCE = 0.00000000000001; + + double total_us_StringToDouble = 0.0; + double total_us_lexical_cast = 0.0; + int64_t numConversions = 0; + + size_t i = 0; + const size_t COUNT = 125; + //const double FACTOR = 1.000000000171271211; + const double FACTOR = 1.71271211; + for (double b = -1.0 * DBL_EPSILON; b < DBL_MAX && i < COUNT; ++i, b *= FACTOR) + { + char txt[1024]; +#if defined(_MSC_VER) + sprintf_s(txt, "%.17f", b); +#else + snprintf(txt, sizeof(txt) - 1, "%.17f", b); +#endif + + + double r = 0.0; + + bool ok = true; + + { + boost::chrono::system_clock::time_point start = boost::chrono::system_clock::now(); + for (size_t i = 0; i < NUM_TIMINGS_CONVS; ++i) + { + ok = StringToDouble(r, txt); + } + boost::chrono::system_clock::time_point end = boost::chrono::system_clock::now(); + boost::chrono::microseconds elapsed = + boost::chrono::duration_cast<boost::chrono::microseconds>(end - start); + total_us_StringToDouble += elapsed.count(); + } + + { + boost::chrono::system_clock::time_point start = boost::chrono::system_clock::now(); + for (size_t i = 0; i < NUM_TIMINGS_CONVS; ++i) + { + try + { + r = boost::lexical_cast<double>(txt); + ok = true; + } + catch (boost::bad_lexical_cast& ) + { + ok = false; + } + } + boost::chrono::system_clock::time_point end = boost::chrono::system_clock::now(); + boost::chrono::microseconds elapsed = + boost::chrono::duration_cast<boost::chrono::microseconds>(end - start); + total_us_lexical_cast += elapsed.count(); + } + numConversions += NUM_TIMINGS_CONVS; + +#if 0 + if (ok) + { + printf("OK for txt = \"%s\" and r = %.17f\n", txt, r); + } + else + { + printf("Not ok for txt = \"%s\" and r = %.17f\n", txt, r); + ok = StringToDouble(r, txt); + } +#endif + + EXPECT_TRUE(ok); + +#if 0 + if (fabs(b - r) > TOLERANCE) + { + printf("fabs(b (%.17f) - r (%.17f)) ((%.17f)) > TOLERANCE (%.17f)\n", b, r, fabs(b - r), TOLERANCE); + } +#endif + EXPECT_NEAR(b, r, TOLERANCE); + } + std::cout << "Total time (us) for " << numConversions + << " conversions using StringToDouble (with NO scientific notation) = " + << static_cast<int64_t>(total_us_StringToDouble) << std::endl; + + std::cout << "Time per conversion using StringToDouble (ns) = " + << (int64_t)( (total_us_StringToDouble * 1000) /((double)numConversions)) << std::endl; + + std::cout << "Total time (us) for " << numConversions + << " conversions using boost::lexical_cast (with NO scientific notation) = " + << static_cast<int64_t>(total_us_lexical_cast) << std::endl; + + std::cout << "Time per conversion using boost::lexical_cast (ns) = " + << (int64_t)( (total_us_lexical_cast * 1000) / ((double)numConversions)) << std::endl; + + std::cout << "StringToDouble is " << (int)((total_us_lexical_cast / total_us_StringToDouble) + 0.5) << " times faster than boost::lexical_cast" << std::endl; + +} +//4444444444444444$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + TEST(GenericToolbox, TestStringToDoubleHardScientific) { @@ -3953,6 +4064,117 @@ } +TEST(GenericToolbox, TestStringToDoubleHardNegScientific_lexical_cast_vs_StringToDouble) +{ + using OrthancStone::GenericToolbox::StringToDouble; + const double TOLERANCE = 0.00000000000001; + + size_t i = 0; + const size_t COUNT = 125; + //const double FACTOR = 1.000000000171271211; + const double FACTOR = 1.71271211; + + double total_us_StringToDouble = 0.0; + double total_us_lexical_cast = 0.0; + int64_t numConversions = 0; + + for (double b = -1.0 * DBL_EPSILON; b < DBL_MAX && i < COUNT; ++i, b *= FACTOR) + { + // the tolerance must be adapted depending on the exponent + double exponent = (b == 0) ? 0 : 1.0 + std::floor(std::log10(std::fabs(b))); + double actualTolerance = TOLERANCE * pow(10.0, exponent); + + char txt[1024]; +#if defined(_MSC_VER) + sprintf_s(txt, "%.17e", b); +#else + snprintf(txt, sizeof(txt) - 1, "%.17e", b); +#endif + double r = 0.0; + + bool ok = true; + + { + boost::chrono::system_clock::time_point start = boost::chrono::system_clock::now(); + for (size_t i = 0; i < NUM_TIMINGS_CONVS; ++i) + { + ok = StringToDouble(r, txt); + } + boost::chrono::system_clock::time_point end = boost::chrono::system_clock::now(); + boost::chrono::microseconds elapsed = + boost::chrono::duration_cast<boost::chrono::microseconds>(end - start); + total_us_StringToDouble += elapsed.count(); + } + + { + boost::chrono::system_clock::time_point start = boost::chrono::system_clock::now(); + for (size_t i = 0; i < NUM_TIMINGS_CONVS; ++i) + { + try + { + r = boost::lexical_cast<double>(txt); + ok = true; + } + catch (boost::bad_lexical_cast& ) + { + ok = false; + } + } + boost::chrono::system_clock::time_point end = boost::chrono::system_clock::now(); + boost::chrono::microseconds elapsed = + boost::chrono::duration_cast<boost::chrono::microseconds>(end - start); + total_us_lexical_cast += elapsed.count(); + } + numConversions += NUM_TIMINGS_CONVS; + +#if 0 + if (ok) + { + printf("OK for txt = \"%s\" and r = %.17e\n", txt, r); + } + else + { + printf("Not ok for txt = \"%s\" and r = %.17e\n", txt, r); + ok = StringToDouble(r, txt); + } +#endif + + EXPECT_TRUE(ok); + +#if 0 + if (fabs(b - r) > actualTolerance) + { + printf("NOK fabs(b (%.17f) - r (%.17f)) ((%.17f)) > actualTolerance (%.17f)\n", b, r, fabs(b - r), actualTolerance); + printf("NOK fabs(b (%.17e) - r (%.17e)) ((%.17e)) > actualTolerance (%.17e)\n", b, r, fabs(b - r), actualTolerance); + ok = StringToDouble(r, txt); + } + else + { + printf("OK fabs(b (%.17f) - r (%.17f)) ((%.17f)) <= actualTolerance (%.17f)\n", b, r, fabs(b - r), actualTolerance); + printf("OK fabs(b (%.17e) - r (%.17e)) ((%.17e)) <= actualTolerance (%.17e)\n", b, r, fabs(b - r), actualTolerance); + } +#endif + EXPECT_NEAR(b, r, actualTolerance); + } + + std::cout << "Total time (us) for " << numConversions + << " conversions using StringToDouble (WITH scientific notation) = " + << static_cast<int64_t>(total_us_StringToDouble) << std::endl; + + std::cout << "Time per conversion using StringToDouble (ns) = " + << (int64_t)( (total_us_StringToDouble*1000) / ((double)numConversions)) << std::endl; + + std::cout << "Total time (us) for " << numConversions + << " conversions using boost::lexical_cast (WITH scientific notation) = " + << static_cast<int64_t>(total_us_lexical_cast) << std::endl; + + std::cout << "Time per conversion using boost::lexical_cast (ns) = " + << (int64_t)( (total_us_lexical_cast * 1000) / ((double)numConversions)) << std::endl; + + std::cout << "StringToDouble is " << (int)((total_us_lexical_cast / total_us_StringToDouble)+ 0.5) << " times faster than boost::lexical_cast" << std::endl; +} + + TEST(GenericToolbox, TestStringToIntegerHard) { using OrthancStone::GenericToolbox::StringToInteger;