Skip to content

ibireme/c_numconv_benchmark

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Number Conversion Benchmark in C

This project evaluates the performance of functions that convert numbers to and from strings in C/C++.

The functions named yy is implemented or rewritten by me, and used in the yyjson library.

Requirement

  • A modern compiler or IDE supporting C11 and C++17.
  • CMake 3.14+ for building this project.
  • Git for interacting with the submodule in this repository.

Building

Clone this repository and initialize submodules:

git clone https://github.com/ibireme/c_numconv_benchmark.git
cd c_numconv_benchmark
git submodule update --init

Build and run:

mkdir build
cd build
cmake ..
cmake --build . --config Release
./run_itoa -o report_itoa.html
./run_atoi -o report_atoi.html
./run_dtoa -o report_dtoa.html
./run_strtod -o report_strtod.html

If you want to build with other compiler or IDE, try these commands:

# Clang for Linux/Unix:
cmake .. -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++

# Microsoft Visual Studio for Windows:
cmake .. -G "Visual Studio 16 2019" -A x64
cmake .. -G "Visual Studio 16 2019" -A Win32

# Xcode for macOS:
cmake .. -G Xcode

# Xcode for iOS:
cmake .. -G Xcode -DCMAKE_SYSTEM_NAME=iOS

Make the results more stable and accurate

This benchmark project uses cpu cycle for measurement, so Turbo Boost and similar technologies should be disabled to make the result more stable and accurate:

Functions


Integer to String (itoa)

Function prototype:

char *itoa_u32(uint32_t val, char *buf);
char *itoa_i32(int32_t val, char *buf);
char *itoa_u64(uint64_t val, char *buf);
char *itoa_i64(int64_t val, char *buf);

img img

Click these links to see more reports with interactive charts:

Note:

  • The yyjson_large_lut uses a large look-up table, and may not be suitable for common cases.

String to Integer (atoi)

Function prototype:

// Function prototype:
typedef enum {
    atoi_result_suc = 0,
    atoi_result_fail = 1,
    atoi_result_overflow = 2,
} atoi_result;

uint32_t atoi_u32(const char *str, size_t len, char **endptr, atoi_result *res);
int32_t atoi_i32(const char *str, size_t len, char **endptr, atoi_result *res);
uint64_t atoi_u64(const char *str, size_t len, char **endptr, atoi_result *res);
int64_t atoi_i64(const char *str, size_t len, char **endptr, atoi_result *res);

img img

Click these links to see more reports with interactive charts:


Double to String (dtoa)

Function prototype:

// Function prototype:
char *dtoa(double val, char *buf);

img img img

Click these links to see more reports with interactive charts:

Note: the following functions may not generate shortest decimal representation, or may not remove the trailing zeros in fraction part:

  • fpconv
  • milo
  • emyg
  • erthink

String to Double (strtod)

Function prototype:

// Function prototype:
double strtod(const char *str, size_t len, char **endptr);

img img img

Click these links to see more reports with interactive charts:

Note:

  • abseil may returns inaccurate result with 0-1 ulp error in some cases.
  • yy_fast may returns inaccurate result with 0-2 ulp error in some cases.
  • ryu and lemire may reject some integer number or large number.

Referenced libraries and articles

google (double<->string)

Efficient binary-decimal and decimal-binary conversion routines for IEEE doubles https://github.com/google/double-conversion

Swift (double->string)

Convert double to string quickly and accurately https://github.com/apple/swift/blob/master/stdlib/public/runtime/SwiftDtoa.cpp apple/swift#16178

David Gay (double<->string)

ANSI C source for functions strtod and dtoa http://www.netlib.org/fp/

fmtlib (double->string, integer->string)

A modern formatting library for C++ https://github.com/fmtlib/fmt https://github.com/fmtlib/format-benchmark fmtlib/fmt#1882

abseil (double<->string, integer<->string)

A C++ Common Libraries https://github.com/abseil/abseil-cpp

ryu (double<->string)

Converts floating point numbers to decimal strings https://github.com/ulfjack/ryu

dragonbox and grisu-exact (double->string)

Implementation of Dragonbox in C++ https://www.reddit.com/r/cpp/comments/ishdj9/updates_in_dragonbox/ https://github.com/jk-jeon/dragonbox https://github.com/jk-jeon/Grisu-Exact https://github.com/jk-jeon/dtoa-benchmark

fast_double_parser (string->double)

Fast function to parse strings into double by lemire https://github.com/lemire/fast_double_parser

itoa benchmark (integer->string)

C++ integer-to-string conversion benchmark https://github.com/miloyip/itoa-benchmark

dtoa benchmark (double->string)

C++ double-to-string conversion benchmark https://github.com/miloyip/dtoa-benchmark

AppNexus (integer->string)

Print integers faster https://www.reddit.com/r/programming/comments/7ljzty/how_to_print_integers_really_fast_with_source_code/ https://medium.com/xandr-tech/appnexus-common-framework-its-out-also-how-to-print-integers-faster-ceb72ac171a1 https://github.com/appnexus/acf/blob/master/src/an_itoa.c

benchmark (string->integer)

https://medium.com/@julienjorge/benchmarking-atoui-a-follow-up-to-writing-fast-code-90e722590f4d https://github.com/j-jorge/atoi-benchmark

benchmark (double->string, integer->string) https://github.com/miloyip/dtoa-benchmark https://github.com/miloyip/itoa-benchmark

License

This project is distributed under the MIT license.