tests: add benchmark for fast_atof()
This commit is contained in:
parent
decb5fedc7
commit
8c5aea272f
@ -29,10 +29,12 @@ file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/temp)
|
|||||||
set(GMIO_TEST_CORE_SRC
|
set(GMIO_TEST_CORE_SRC
|
||||||
main_test_core.c
|
main_test_core.c
|
||||||
test_core.c
|
test_core.c
|
||||||
|
test_core_benchmark_fast_atof.c
|
||||||
test_core_internal.c
|
test_core_internal.c
|
||||||
test_core_platform.c
|
test_core_platform.c
|
||||||
core_utils.c
|
core_utils.c
|
||||||
stream_buffer.c)
|
stream_buffer.c
|
||||||
|
../benchmarks/commons/benchmark_tools.c)
|
||||||
if(GMIO_BUILD_SHARED_LIBS)
|
if(GMIO_BUILD_SHARED_LIBS)
|
||||||
# Note_1: MSVC wants it because internal symbols are not exported (GCC
|
# Note_1: MSVC wants it because internal symbols are not exported (GCC
|
||||||
# exports all symbols)
|
# exports all symbols)
|
||||||
|
@ -23,10 +23,10 @@ const char* test_core__stream();
|
|||||||
const char* test_internal__byte_swap();
|
const char* test_internal__byte_swap();
|
||||||
const char* test_internal__byte_codec();
|
const char* test_internal__byte_codec();
|
||||||
const char* test_internal__fast_atof();
|
const char* test_internal__fast_atof();
|
||||||
const char* test_internal__gmio_fast_atof();
|
|
||||||
const char* test_internal__safe_cast();
|
const char* test_internal__safe_cast();
|
||||||
const char* test_internal__stringstream();
|
const char* test_internal__stringstream();
|
||||||
const char* test_internal__string_utils();
|
const char* test_internal__string_utils();
|
||||||
|
const char* test_internal__benchmark_gmio_fast_atof();
|
||||||
|
|
||||||
const char* test_platform__alignment();
|
const char* test_platform__alignment();
|
||||||
const char* test_platform__global_h();
|
const char* test_platform__global_h();
|
||||||
@ -44,10 +44,10 @@ const char* all_tests()
|
|||||||
UTEST_RUN(test_internal__byte_swap);
|
UTEST_RUN(test_internal__byte_swap);
|
||||||
UTEST_RUN(test_internal__byte_codec);
|
UTEST_RUN(test_internal__byte_codec);
|
||||||
UTEST_RUN(test_internal__fast_atof);
|
UTEST_RUN(test_internal__fast_atof);
|
||||||
UTEST_RUN(test_internal__gmio_fast_atof);
|
|
||||||
UTEST_RUN(test_internal__safe_cast);
|
UTEST_RUN(test_internal__safe_cast);
|
||||||
UTEST_RUN(test_internal__stringstream);
|
UTEST_RUN(test_internal__stringstream);
|
||||||
UTEST_RUN(test_internal__string_utils);
|
UTEST_RUN(test_internal__string_utils);
|
||||||
|
UTEST_RUN(test_internal__benchmark_gmio_fast_atof);
|
||||||
|
|
||||||
UTEST_RUN(test_platform__alignment);
|
UTEST_RUN(test_platform__alignment);
|
||||||
UTEST_RUN(test_platform__global_h);
|
UTEST_RUN(test_platform__global_h);
|
||||||
|
183
tests/test_core_benchmark_fast_atof.c
Normal file
183
tests/test_core_benchmark_fast_atof.c
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
** gmio
|
||||||
|
** Copyright Fougue (2 Mar. 2015)
|
||||||
|
** contact@fougue.pro
|
||||||
|
**
|
||||||
|
** This software is a reusable library whose purpose is to provide complete
|
||||||
|
** I/O support for various CAD file formats (eg. STL)
|
||||||
|
**
|
||||||
|
** This software is governed by the CeCILL-B license under French law and
|
||||||
|
** abiding by the rules of distribution of free software. You can use,
|
||||||
|
** modify and/ or redistribute the software under the terms of the CeCILL-B
|
||||||
|
** license as circulated by CEA, CNRS and INRIA at the following URL
|
||||||
|
** "http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html".
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "utest_assert.h"
|
||||||
|
|
||||||
|
#include "../benchmarks/commons/benchmark_tools.h"
|
||||||
|
#include "../src/gmio_core/internal/fast_atof.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
static const float float_array[] = {
|
||||||
|
1145816.0615274f,
|
||||||
|
859213.75982427f,
|
||||||
|
966810.0021625f,
|
||||||
|
116009.39334184f,
|
||||||
|
-71263.236445963f,
|
||||||
|
1632844.0273334f,
|
||||||
|
56876.761679015f,
|
||||||
|
1670907.7036338f,
|
||||||
|
1437992.5029064f,
|
||||||
|
706598.88550015f,
|
||||||
|
1912856.6587869f,
|
||||||
|
-74873.963359219f,
|
||||||
|
861707.30952253f,
|
||||||
|
251769.8571327f,
|
||||||
|
1699911.3574624f,
|
||||||
|
187482.6645886f,
|
||||||
|
635324.18922303f,
|
||||||
|
825239.16816583f,
|
||||||
|
923229.60096562f,
|
||||||
|
1671951.443363f,
|
||||||
|
1229446.7883787f,
|
||||||
|
757413.85596684f,
|
||||||
|
-14473.833429848f,
|
||||||
|
1322835.7150326f,
|
||||||
|
-33251.199514256f,
|
||||||
|
1531123.3647313f,
|
||||||
|
528501.5790856f,
|
||||||
|
436167.23596871f,
|
||||||
|
14397.062228246f,
|
||||||
|
1454939.7571268f,
|
||||||
|
1692972.0920012f,
|
||||||
|
1780646.3084559f,
|
||||||
|
989713.49335728f,
|
||||||
|
1541628.0544557f,
|
||||||
|
10818.210575179f,
|
||||||
|
193697.32038756f,
|
||||||
|
459958.03305877f,
|
||||||
|
386664.66157262f,
|
||||||
|
1424156.8543595f,
|
||||||
|
1737569.8573131f,
|
||||||
|
998766.07898565f,
|
||||||
|
1498818.5395481f,
|
||||||
|
1245966.4099132f,
|
||||||
|
1455428.7210365f,
|
||||||
|
197385.08439501f,
|
||||||
|
879153.40041702f,
|
||||||
|
-82192.77676297f,
|
||||||
|
899980.71459121f,
|
||||||
|
442951.18727859f,
|
||||||
|
429733.95261435f,
|
||||||
|
-91807.596567929f,
|
||||||
|
242590.54984087f,
|
||||||
|
38434.983528422f,
|
||||||
|
1438265.2223754f,
|
||||||
|
94147.7701972f,
|
||||||
|
1883829.7321852f,
|
||||||
|
692408.39047935f,
|
||||||
|
1102390.5784368f,
|
||||||
|
1195454.442173f,
|
||||||
|
1016988.4061986f,
|
||||||
|
329433.38976681f,
|
||||||
|
34867.718878606f,
|
||||||
|
1139500.6440764f,
|
||||||
|
1105145.6145966f,
|
||||||
|
857621.72278837f,
|
||||||
|
385386.37328212f,
|
||||||
|
99213.089933252f,
|
||||||
|
1057370.9274909f,
|
||||||
|
618583.85429652f,
|
||||||
|
243663.42967547f,
|
||||||
|
953197.6427665f,
|
||||||
|
1965283.5770814f,
|
||||||
|
1104619.5847935f,
|
||||||
|
260492.339805f,
|
||||||
|
234207.59892753f,
|
||||||
|
1614202.0538515f,
|
||||||
|
1189281.6673914f,
|
||||||
|
1554272.0507617f,
|
||||||
|
1025472.5255656f,
|
||||||
|
1222277.3171599f,
|
||||||
|
1453022.1682289f,
|
||||||
|
1456530.4573889f,
|
||||||
|
-85452.126751399f,
|
||||||
|
12215.028755467f,
|
||||||
|
1387416.2917898f,
|
||||||
|
1526189.9514246f,
|
||||||
|
1610725.9704781f,
|
||||||
|
190781.76379706f,
|
||||||
|
854656.48162861f,
|
||||||
|
1351074.6843419f,
|
||||||
|
551066.49000713f,
|
||||||
|
52031.184291482f,
|
||||||
|
1173924.6147098f,
|
||||||
|
723591.50886703f,
|
||||||
|
1147671.5720946f,
|
||||||
|
918000.17292518f,
|
||||||
|
1489562.4640815f,
|
||||||
|
509914.95117076f,
|
||||||
|
716195.46181345f,
|
||||||
|
1981909.6994968f,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void test_internal__run_atof(float (*func_atof)(const char*))
|
||||||
|
{
|
||||||
|
size_t iter;
|
||||||
|
for (iter = 0; iter < 1000; ++iter) {
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < GMIO_ARRAY_SIZE(float_array); ++i) {
|
||||||
|
char strbuff[512] = {0};
|
||||||
|
const float f = float_array[i];
|
||||||
|
float fres = 0.f;
|
||||||
|
sprintf(strbuff, "%f", f);
|
||||||
|
fres = func_atof(strbuff);
|
||||||
|
sprintf(strbuff, "%E", f);
|
||||||
|
fres = func_atof(strbuff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static float float_strtod(const char* str)
|
||||||
|
{
|
||||||
|
return (float)strtod(str, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void benchmark_fast_atof(const char* dummy)
|
||||||
|
{
|
||||||
|
GMIO_UNUSED(dummy);
|
||||||
|
test_internal__run_atof(&fast_atof);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void benchmark_strtod(const char* dummy)
|
||||||
|
{
|
||||||
|
GMIO_UNUSED(dummy);
|
||||||
|
test_internal__run_atof(&float_strtod);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* test_internal__benchmark_gmio_fast_atof()
|
||||||
|
{
|
||||||
|
struct benchmark_cmp_arg bmk_arg[] = {
|
||||||
|
{ "str->float", &benchmark_fast_atof, NULL, &benchmark_strtod, NULL },
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
struct benchmark_cmp_result bmk_res = {0};
|
||||||
|
const struct benchmark_cmp_result_header header = { "fast_atof", "strtod" };
|
||||||
|
struct benchmark_cmp_result_array bmk_res_array = {0};
|
||||||
|
|
||||||
|
benchmark_cmp_batch(2, bmk_arg, &bmk_res, NULL, NULL);
|
||||||
|
bmk_res_array.ptr = &bmk_res;
|
||||||
|
bmk_res_array.count = 1;
|
||||||
|
puts("\n");
|
||||||
|
benchmark_print_results(
|
||||||
|
BENCHMARK_PRINT_FORMAT_MARKDOWN,
|
||||||
|
header,
|
||||||
|
bmk_res_array);
|
||||||
|
|
||||||
|
UTEST_ASSERT((1.2*bmk_res.func1_exec_time_ms) < bmk_res.func2_exec_time_ms);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
@ -24,6 +24,7 @@
|
|||||||
#include "../src/gmio_core/internal/numeric_utils.h"
|
#include "../src/gmio_core/internal/numeric_utils.h"
|
||||||
#include "../src/gmio_core/internal/safe_cast.h"
|
#include "../src/gmio_core/internal/safe_cast.h"
|
||||||
#include "../src/gmio_core/internal/stringstream.h"
|
#include "../src/gmio_core/internal/stringstream.h"
|
||||||
|
#include "../src/gmio_core/internal/stringstream_fast_atof.h"
|
||||||
#include "../src/gmio_core/internal/string_utils.h"
|
#include "../src/gmio_core/internal/string_utils.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -60,29 +61,59 @@ const char* test_internal__byte_codec()
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gmio_bool_t gmio_test_calculation_atof(const char* value_str)
|
static void gmio_test_atof_fprintf_err(
|
||||||
|
const char* func_fast_atof_str,
|
||||||
|
const char* val_str,
|
||||||
|
float fast_val,
|
||||||
|
float std_val)
|
||||||
{
|
{
|
||||||
const gmio_float32_t fast_value = fast_atof(value_str);
|
|
||||||
const gmio_float32_t std_value = (gmio_float32_t)strtod(value_str, NULL);
|
|
||||||
const gmio_bool_t accurate =
|
|
||||||
gmio_float32_ulp_equals(fast_value, std_value, 1);
|
|
||||||
if (!accurate) {
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"*** ERROR: fast_atof() less accurate than strtod()\n"
|
"*** ERROR: %s() less accurate than strtod()\n"
|
||||||
" value_str : \"%s\"\n"
|
" value_str : \"%s\"\n"
|
||||||
" fast_value: %.12f (%s) as_int: 0x%x\n"
|
" fast_value: %.12f (%s) as_int: 0x%x\n"
|
||||||
" std_value : %.12f (%s) as_int: 0x%x\n"
|
" std_value : %.12f (%s) as_int: 0x%x\n"
|
||||||
" ulp_diff : %u\n",
|
" ulp_diff : %u\n",
|
||||||
value_str,
|
func_fast_atof_str,
|
||||||
fast_value,
|
val_str,
|
||||||
gmio_float32_sign(fast_value) > 0 ? "+" : "-",
|
fast_val,
|
||||||
gmio_convert_uint32(fast_value),
|
gmio_float32_sign(fast_val) > 0 ? "+" : "-",
|
||||||
std_value,
|
gmio_convert_uint32(fast_val),
|
||||||
gmio_float32_sign(std_value) > 0 ? "+" : "-",
|
std_val,
|
||||||
gmio_convert_uint32(std_value),
|
gmio_float32_sign(std_val) > 0 ? "+" : "-",
|
||||||
gmio_float32_ulp_diff(fast_value, std_value));
|
gmio_convert_uint32(std_val),
|
||||||
|
gmio_float32_ulp_diff(fast_val, std_val));
|
||||||
}
|
}
|
||||||
return accurate;
|
|
||||||
|
static gmio_bool_t gmio_test_calculation_atof(const char* val_str)
|
||||||
|
{
|
||||||
|
const gmio_float32_t std_val = (gmio_float32_t)strtod(val_str, NULL);
|
||||||
|
int accurate_count = 0;
|
||||||
|
|
||||||
|
{ /* Test fast_atof() */
|
||||||
|
const gmio_float32_t fast_val = fast_atof(val_str);
|
||||||
|
if (gmio_float32_ulp_equals(fast_val, std_val, 1))
|
||||||
|
++accurate_count;
|
||||||
|
else
|
||||||
|
gmio_test_atof_fprintf_err("fast_atof", val_str, fast_val, std_val);
|
||||||
|
}
|
||||||
|
|
||||||
|
{ /* Test gmio_stringstream_fast_atof() */
|
||||||
|
char iobuff[512] = {0};
|
||||||
|
struct gmio_ro_buffer ibuff = gmio_ro_buffer(val_str, strlen(val_str), 0);
|
||||||
|
struct gmio_stringstream sstream = gmio_stringstream(
|
||||||
|
gmio_istream_buffer(&ibuff),
|
||||||
|
gmio_string(iobuff, 0, GMIO_ARRAY_SIZE(iobuff)));
|
||||||
|
const gmio_float32_t fast_val = gmio_stringstream_fast_atof(&sstream);
|
||||||
|
if (gmio_float32_ulp_equals(fast_val, std_val, 1)) {
|
||||||
|
++accurate_count;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
gmio_test_atof_fprintf_err(
|
||||||
|
"gmio_stringstream_fast_atof", val_str, fast_val, std_val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return accurate_count == 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* test_internal__fast_atof()
|
const char* test_internal__fast_atof()
|
||||||
@ -124,30 +155,6 @@ const char* test_internal__fast_atof()
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* test_internal__gmio_fast_atof()
|
|
||||||
{
|
|
||||||
static const char fstr[] = "1234.567E05";
|
|
||||||
const float f1 = fast_atof(fstr);
|
|
||||||
|
|
||||||
{
|
|
||||||
char strbuff[2048] = {0};
|
|
||||||
struct gmio_stringstream sstream = {0};
|
|
||||||
struct gmio_ro_buffer streambuff = { fstr, sizeof(fstr) - 1, 0 };
|
|
||||||
float f2;
|
|
||||||
|
|
||||||
sstream.stream = gmio_istream_buffer(&streambuff);
|
|
||||||
sstream.strbuff.ptr = &strbuff[0];
|
|
||||||
sstream.strbuff.max_len = sizeof(strbuff) - 1;
|
|
||||||
gmio_stringstream_init(&sstream);
|
|
||||||
|
|
||||||
f2 = gmio_stringstream_fast_atof(&sstream);
|
|
||||||
|
|
||||||
UTEST_ASSERT(gmio_float32_ulp_equals(f1, f2, 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* test_internal__safe_cast()
|
const char* test_internal__safe_cast()
|
||||||
{
|
{
|
||||||
#if GMIO_TARGET_ARCH_BIT_SIZE > 32
|
#if GMIO_TARGET_ARCH_BIT_SIZE > 32
|
||||||
|
Loading…
Reference in New Issue
Block a user