Mercurial > hg > orthanc-stone
comparison UnitTestsSources/GenericToolboxTests.cpp @ 1183:2e52d1f4c9e3 broker
merge
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 22 Nov 2019 08:58:46 +0100 |
parents | ba08f2b0a779 3076a8a66db5 |
children | 09fc591d8ff9 |
comparison
equal
deleted
inserted
replaced
1180:9c8f557ea799 | 1183:2e52d1f4c9e3 |
---|---|
17 * You should have received a copy of the GNU Affero General Public License | 17 * You should have received a copy of the GNU Affero General Public License |
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. | 18 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
19 **/ | 19 **/ |
20 | 20 |
21 #include <Framework/Toolbox/GenericToolbox.h> | 21 #include <Framework/Toolbox/GenericToolbox.h> |
22 | |
23 #include <boost/chrono.hpp> | |
24 #include <boost/lexical_cast.hpp> | |
22 | 25 |
23 #include "gtest/gtest.h" | 26 #include "gtest/gtest.h" |
24 | 27 |
25 #include "stdint.h" | 28 #include "stdint.h" |
26 | 29 |
3840 #endif | 3843 #endif |
3841 EXPECT_NEAR(b, r, TOLERANCE); | 3844 EXPECT_NEAR(b, r, TOLERANCE); |
3842 } | 3845 } |
3843 } | 3846 } |
3844 | 3847 |
3848 static const size_t NUM_TIMINGS_CONVS = 2000; | |
3849 | |
3850 | |
3851 //4444444444444444$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ | |
3852 | |
3853 TEST(GenericToolbox, TestStringToDoubleHardNeg_lexical_cast_vs_StringToDouble) | |
3854 { | |
3855 using OrthancStone::GenericToolbox::StringToDouble; | |
3856 const double TOLERANCE = 0.00000000000001; | |
3857 | |
3858 double total_us_StringToDouble = 0.0; | |
3859 double total_us_lexical_cast = 0.0; | |
3860 int64_t numConversions = 0; | |
3861 | |
3862 size_t i = 0; | |
3863 const size_t COUNT = 125; | |
3864 //const double FACTOR = 1.000000000171271211; | |
3865 const double FACTOR = 1.71271211; | |
3866 for (double b = -1.0 * DBL_EPSILON; b < DBL_MAX && i < COUNT; ++i, b *= FACTOR) | |
3867 { | |
3868 char txt[1024]; | |
3869 #if defined(_MSC_VER) | |
3870 sprintf_s(txt, "%.17f", b); | |
3871 #else | |
3872 snprintf(txt, sizeof(txt) - 1, "%.17f", b); | |
3873 #endif | |
3874 | |
3875 | |
3876 double r = 0.0; | |
3877 | |
3878 bool ok = true; | |
3879 | |
3880 { | |
3881 boost::chrono::system_clock::time_point start = boost::chrono::system_clock::now(); | |
3882 for (size_t i = 0; i < NUM_TIMINGS_CONVS; ++i) | |
3883 { | |
3884 ok = StringToDouble(r, txt); | |
3885 } | |
3886 boost::chrono::system_clock::time_point end = boost::chrono::system_clock::now(); | |
3887 boost::chrono::microseconds elapsed = | |
3888 boost::chrono::duration_cast<boost::chrono::microseconds>(end - start); | |
3889 total_us_StringToDouble += elapsed.count(); | |
3890 } | |
3891 | |
3892 { | |
3893 boost::chrono::system_clock::time_point start = boost::chrono::system_clock::now(); | |
3894 for (size_t i = 0; i < NUM_TIMINGS_CONVS; ++i) | |
3895 { | |
3896 try | |
3897 { | |
3898 r = boost::lexical_cast<double>(txt); | |
3899 ok = true; | |
3900 } | |
3901 catch (boost::bad_lexical_cast& ) | |
3902 { | |
3903 ok = false; | |
3904 } | |
3905 } | |
3906 boost::chrono::system_clock::time_point end = boost::chrono::system_clock::now(); | |
3907 boost::chrono::microseconds elapsed = | |
3908 boost::chrono::duration_cast<boost::chrono::microseconds>(end - start); | |
3909 total_us_lexical_cast += elapsed.count(); | |
3910 } | |
3911 numConversions += NUM_TIMINGS_CONVS; | |
3912 | |
3913 #if 0 | |
3914 if (ok) | |
3915 { | |
3916 printf("OK for txt = \"%s\" and r = %.17f\n", txt, r); | |
3917 } | |
3918 else | |
3919 { | |
3920 printf("Not ok for txt = \"%s\" and r = %.17f\n", txt, r); | |
3921 ok = StringToDouble(r, txt); | |
3922 } | |
3923 #endif | |
3924 | |
3925 EXPECT_TRUE(ok); | |
3926 | |
3927 #if 0 | |
3928 if (fabs(b - r) > TOLERANCE) | |
3929 { | |
3930 printf("fabs(b (%.17f) - r (%.17f)) ((%.17f)) > TOLERANCE (%.17f)\n", b, r, fabs(b - r), TOLERANCE); | |
3931 } | |
3932 #endif | |
3933 EXPECT_NEAR(b, r, TOLERANCE); | |
3934 } | |
3935 std::cout << "Total time (us) for " << numConversions | |
3936 << " conversions using StringToDouble (with NO scientific notation) = " | |
3937 << static_cast<int64_t>(total_us_StringToDouble) << std::endl; | |
3938 | |
3939 std::cout << "Time per conversion using StringToDouble (ns) = " | |
3940 << (int64_t)( (total_us_StringToDouble * 1000) /((double)numConversions)) << std::endl; | |
3941 | |
3942 std::cout << "Total time (us) for " << numConversions | |
3943 << " conversions using boost::lexical_cast (with NO scientific notation) = " | |
3944 << static_cast<int64_t>(total_us_lexical_cast) << std::endl; | |
3945 | |
3946 std::cout << "Time per conversion using boost::lexical_cast (ns) = " | |
3947 << (int64_t)( (total_us_lexical_cast * 1000) / ((double)numConversions)) << std::endl; | |
3948 | |
3949 std::cout << "StringToDouble is " << (int)((total_us_lexical_cast / total_us_StringToDouble) + 0.5) << " times faster than boost::lexical_cast" << std::endl; | |
3950 | |
3951 } | |
3952 //4444444444444444$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ | |
3953 | |
3845 | 3954 |
3846 TEST(GenericToolbox, TestStringToDoubleHardScientific) | 3955 TEST(GenericToolbox, TestStringToDoubleHardScientific) |
3847 { | 3956 { |
3848 using OrthancStone::GenericToolbox::StringToDouble; | 3957 using OrthancStone::GenericToolbox::StringToDouble; |
3849 const double TOLERANCE = 0.00000000000001; | 3958 const double TOLERANCE = 0.00000000000001; |
3953 EXPECT_NEAR(b, r, actualTolerance); | 4062 EXPECT_NEAR(b, r, actualTolerance); |
3954 } | 4063 } |
3955 } | 4064 } |
3956 | 4065 |
3957 | 4066 |
4067 TEST(GenericToolbox, TestStringToDoubleHardNegScientific_lexical_cast_vs_StringToDouble) | |
4068 { | |
4069 using OrthancStone::GenericToolbox::StringToDouble; | |
4070 const double TOLERANCE = 0.00000000000001; | |
4071 | |
4072 size_t i = 0; | |
4073 const size_t COUNT = 125; | |
4074 //const double FACTOR = 1.000000000171271211; | |
4075 const double FACTOR = 1.71271211; | |
4076 | |
4077 double total_us_StringToDouble = 0.0; | |
4078 double total_us_lexical_cast = 0.0; | |
4079 int64_t numConversions = 0; | |
4080 | |
4081 for (double b = -1.0 * DBL_EPSILON; b < DBL_MAX && i < COUNT; ++i, b *= FACTOR) | |
4082 { | |
4083 // the tolerance must be adapted depending on the exponent | |
4084 double exponent = (b == 0) ? 0 : 1.0 + std::floor(std::log10(std::fabs(b))); | |
4085 double actualTolerance = TOLERANCE * pow(10.0, exponent); | |
4086 | |
4087 char txt[1024]; | |
4088 #if defined(_MSC_VER) | |
4089 sprintf_s(txt, "%.17e", b); | |
4090 #else | |
4091 snprintf(txt, sizeof(txt) - 1, "%.17e", b); | |
4092 #endif | |
4093 double r = 0.0; | |
4094 | |
4095 bool ok = true; | |
4096 | |
4097 { | |
4098 boost::chrono::system_clock::time_point start = boost::chrono::system_clock::now(); | |
4099 for (size_t i = 0; i < NUM_TIMINGS_CONVS; ++i) | |
4100 { | |
4101 ok = StringToDouble(r, txt); | |
4102 } | |
4103 boost::chrono::system_clock::time_point end = boost::chrono::system_clock::now(); | |
4104 boost::chrono::microseconds elapsed = | |
4105 boost::chrono::duration_cast<boost::chrono::microseconds>(end - start); | |
4106 total_us_StringToDouble += elapsed.count(); | |
4107 } | |
4108 | |
4109 { | |
4110 boost::chrono::system_clock::time_point start = boost::chrono::system_clock::now(); | |
4111 for (size_t i = 0; i < NUM_TIMINGS_CONVS; ++i) | |
4112 { | |
4113 try | |
4114 { | |
4115 r = boost::lexical_cast<double>(txt); | |
4116 ok = true; | |
4117 } | |
4118 catch (boost::bad_lexical_cast& ) | |
4119 { | |
4120 ok = false; | |
4121 } | |
4122 } | |
4123 boost::chrono::system_clock::time_point end = boost::chrono::system_clock::now(); | |
4124 boost::chrono::microseconds elapsed = | |
4125 boost::chrono::duration_cast<boost::chrono::microseconds>(end - start); | |
4126 total_us_lexical_cast += elapsed.count(); | |
4127 } | |
4128 numConversions += NUM_TIMINGS_CONVS; | |
4129 | |
4130 #if 0 | |
4131 if (ok) | |
4132 { | |
4133 printf("OK for txt = \"%s\" and r = %.17e\n", txt, r); | |
4134 } | |
4135 else | |
4136 { | |
4137 printf("Not ok for txt = \"%s\" and r = %.17e\n", txt, r); | |
4138 ok = StringToDouble(r, txt); | |
4139 } | |
4140 #endif | |
4141 | |
4142 EXPECT_TRUE(ok); | |
4143 | |
4144 #if 0 | |
4145 if (fabs(b - r) > actualTolerance) | |
4146 { | |
4147 printf("NOK fabs(b (%.17f) - r (%.17f)) ((%.17f)) > actualTolerance (%.17f)\n", b, r, fabs(b - r), actualTolerance); | |
4148 printf("NOK fabs(b (%.17e) - r (%.17e)) ((%.17e)) > actualTolerance (%.17e)\n", b, r, fabs(b - r), actualTolerance); | |
4149 ok = StringToDouble(r, txt); | |
4150 } | |
4151 else | |
4152 { | |
4153 printf("OK fabs(b (%.17f) - r (%.17f)) ((%.17f)) <= actualTolerance (%.17f)\n", b, r, fabs(b - r), actualTolerance); | |
4154 printf("OK fabs(b (%.17e) - r (%.17e)) ((%.17e)) <= actualTolerance (%.17e)\n", b, r, fabs(b - r), actualTolerance); | |
4155 } | |
4156 #endif | |
4157 EXPECT_NEAR(b, r, actualTolerance); | |
4158 } | |
4159 | |
4160 std::cout << "Total time (us) for " << numConversions | |
4161 << " conversions using StringToDouble (WITH scientific notation) = " | |
4162 << static_cast<int64_t>(total_us_StringToDouble) << std::endl; | |
4163 | |
4164 std::cout << "Time per conversion using StringToDouble (ns) = " | |
4165 << (int64_t)( (total_us_StringToDouble*1000) / ((double)numConversions)) << std::endl; | |
4166 | |
4167 std::cout << "Total time (us) for " << numConversions | |
4168 << " conversions using boost::lexical_cast (WITH scientific notation) = " | |
4169 << static_cast<int64_t>(total_us_lexical_cast) << std::endl; | |
4170 | |
4171 std::cout << "Time per conversion using boost::lexical_cast (ns) = " | |
4172 << (int64_t)( (total_us_lexical_cast * 1000) / ((double)numConversions)) << std::endl; | |
4173 | |
4174 std::cout << "StringToDouble is " << (int)((total_us_lexical_cast / total_us_StringToDouble)+ 0.5) << " times faster than boost::lexical_cast" << std::endl; | |
4175 } | |
4176 | |
4177 | |
3958 TEST(GenericToolbox, TestStringToIntegerHard) | 4178 TEST(GenericToolbox, TestStringToIntegerHard) |
3959 { | 4179 { |
3960 using OrthancStone::GenericToolbox::StringToInteger; | 4180 using OrthancStone::GenericToolbox::StringToInteger; |
3961 | 4181 |
3962 size_t i = 0; | 4182 size_t i = 0; |