mirror of
https://github.com/fastfloat/fast_float.git
synced 2026-02-13 05:39:55 +08:00
* Added additional compile option FASTFLOAT_TABLE_HACK_CHAR_DIGIT_LUT_DISABLED for improve cache usage in high load.
* Small optimization in code generation for auto vectorization.
This commit is contained in:
parent
7041f91d47
commit
b7fb05b843
12
README.md
12
README.md
@ -383,13 +383,15 @@ int main() {
|
|||||||
There is a really common use case in mathematical and other abstract syntax tree (AST)-like parsers that already processes
|
There is a really common use case in mathematical and other abstract syntax tree (AST)-like parsers that already processes
|
||||||
the sign and all other symbols before any number by itself. In this case you can use FastFloat to only parse positive numbers
|
the sign and all other symbols before any number by itself. In this case you can use FastFloat to only parse positive numbers
|
||||||
in all supported formats with macros `FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN`, which significantly reduce the code size
|
in all supported formats with macros `FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN`, which significantly reduce the code size
|
||||||
and improve performance. You also can use macros `FASTFLOAT_ISNOT_CHECKED_BOUNDS` if your code already checks bounds;
|
and improve performance. An additional option for high performance and very fast processing is
|
||||||
it's very likely because all parsers need to check the first character by itself before parsing. Additionally, you can use
|
`FASTFLOAT_TABLE_HACK_CHAR_DIGIT_LUT_DISABLED`; it reduces data size and speeds up parsing because a data cache is used for your
|
||||||
macros `FASTFLOAT_ONLY_ROUNDS_TO_NEAREST_SUPPORTED` if you only need `FE_TONEAREST` rounding mode in the parsing;
|
real data, not for a 256-byte table that flushes out at least 3 cache lines on x86. You also can use macros
|
||||||
this option also improves performance a bit and reduces code size.
|
`FASTFLOAT_ISNOT_CHECKED_BOUNDS` if your code already checks bounds; it's very likely because all parsers need to check the first
|
||||||
|
character by itself before parsing. Additionally, you can use macros `FASTFLOAT_ONLY_ROUNDS_TO_NEAREST_SUPPORTED` if you only need
|
||||||
|
`FE_TONEAREST` rounding mode in the parsing; this option also improves performance a bit and reduces code size.
|
||||||
```C++
|
```C++
|
||||||
#define FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN
|
#define FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN
|
||||||
|
#define FASTFLOAT_TABLE_HACK_CHAR_DIGIT_LUT_DISABLED
|
||||||
#define FASTFLOAT_ISNOT_CHECKED_BOUNDS
|
#define FASTFLOAT_ISNOT_CHECKED_BOUNDS
|
||||||
#define FASTFLOAT_ONLY_ROUNDS_TO_NEAREST_SUPPORTED
|
#define FASTFLOAT_ONLY_ROUNDS_TO_NEAREST_SUPPORTED
|
||||||
#include "fast_float/fast_float.h"
|
#include "fast_float/fast_float.h"
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
// #define FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN
|
// #define FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN
|
||||||
|
// #define FASTFLOAT_TABLE_HACK_CHAR_DIGIT_LUT_DISABLED
|
||||||
// #define FASTFLOAT_ONLY_ROUNDS_TO_NEAREST_SUPPORTED
|
// #define FASTFLOAT_ONLY_ROUNDS_TO_NEAREST_SUPPORTED
|
||||||
// #define FASTFLOAT_ISNOT_CHECKED_BOUNDS
|
// #define FASTFLOAT_ISNOT_CHECKED_BOUNDS
|
||||||
|
|
||||||
@ -234,6 +235,10 @@ int main(int argc, char **argv) {
|
|||||||
std::cout << "# FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN is enabled"
|
std::cout << "# FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN is enabled"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef FASTFLOAT_TABLE_HACK_CHAR_DIGIT_LUT_DISABLED
|
||||||
|
std::cout << "# FASTFLOAT_TABLE_HACK_CHAR_DIGIT_LUT_DISABLED is enabled"
|
||||||
|
<< std::endl;
|
||||||
|
#endif
|
||||||
#ifdef FASTFLOAT_ONLY_ROUNDS_TO_NEAREST_SUPPORTED
|
#ifdef FASTFLOAT_ONLY_ROUNDS_TO_NEAREST_SUPPORTED
|
||||||
std::cout << "# FASTFLOAT_ONLY_ROUNDS_TO_NEAREST_SUPPORTED is enabled"
|
std::cout << "# FASTFLOAT_ONLY_ROUNDS_TO_NEAREST_SUPPORTED is enabled"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|||||||
@ -642,7 +642,14 @@ parse_int_string(UC const *p, UC const *pend, T &value,
|
|||||||
loop_parse_if_eight_digits(p, pend, i); // use SIMD if possible
|
loop_parse_if_eight_digits(p, pend, i); // use SIMD if possible
|
||||||
}
|
}
|
||||||
while (p != pend) {
|
while (p != pend) {
|
||||||
|
#ifdef FASTFLOAT_TABLE_HACK_CHAR_DIGIT_LUT_DISABLED
|
||||||
|
const auto digit = *p;
|
||||||
|
if (!is_integer(digit)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#else
|
||||||
auto const digit = ch_to_digit(*p);
|
auto const digit = ch_to_digit(*p);
|
||||||
|
#endif
|
||||||
if (digit >= options.base) {
|
if (digit >= options.base) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -513,7 +513,7 @@ typedef int_fast16_t am_pow_t;
|
|||||||
// Bias so we can get the real exponent with an invalid adjusted_mantissa.
|
// Bias so we can get the real exponent with an invalid adjusted_mantissa.
|
||||||
constexpr static am_pow_t invalid_am_bias = -0x8000;
|
constexpr static am_pow_t invalid_am_bias = -0x8000;
|
||||||
|
|
||||||
struct adjusted_mantissa {
|
struct alignas(16) adjusted_mantissa {
|
||||||
am_mant_t mantissa;
|
am_mant_t mantissa;
|
||||||
am_pow_t power2;
|
am_pow_t power2;
|
||||||
adjusted_mantissa() noexcept = default;
|
adjusted_mantissa() noexcept = default;
|
||||||
@ -1201,6 +1201,7 @@ template <> constexpr char8_t const *str_const_inf<char8_t>() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <typename = void> struct int_luts {
|
template <typename = void> struct int_luts {
|
||||||
|
#ifndef FASTFLOAT_TABLE_HACK_CHAR_DIGIT_LUT_DISABLED
|
||||||
static constexpr uint8_t chdigit[] = {
|
static constexpr uint8_t chdigit[] = {
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
@ -1220,6 +1221,7 @@ template <typename = void> struct int_luts {
|
|||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
255};
|
255};
|
||||||
|
#endif
|
||||||
|
|
||||||
static constexpr uint_fast8_t maxdigits_u64[] = {
|
static constexpr uint_fast8_t maxdigits_u64[] = {
|
||||||
64, 41, 32, 28, 25, 23, 22, 21, 20, 19, 18, 18, 17, 17, 16, 16, 16, 16,
|
64, 41, 32, 28, 25, 23, 22, 21, 20, 19, 18, 18, 17, 17, 16, 16, 16, 16,
|
||||||
@ -1250,6 +1252,7 @@ template <typename T> constexpr uint64_t int_luts<T>::min_safe_u64[];
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef FASTFLOAT_TABLE_HACK_CHAR_DIGIT_LUT_DISABLED
|
||||||
template <typename UC>
|
template <typename UC>
|
||||||
fastfloat_really_inline constexpr uint_fast8_t ch_to_digit(UC c) noexcept {
|
fastfloat_really_inline constexpr uint_fast8_t ch_to_digit(UC c) noexcept {
|
||||||
// wchar_t and char can be signed, so we need to be careful.
|
// wchar_t and char can be signed, so we need to be careful.
|
||||||
@ -1259,6 +1262,7 @@ fastfloat_really_inline constexpr uint_fast8_t ch_to_digit(UC c) noexcept {
|
|||||||
static_cast<UnsignedUC>(
|
static_cast<UnsignedUC>(
|
||||||
-((static_cast<UnsignedUC>(c) & ~0xFFull) == 0)))];
|
-((static_cast<UnsignedUC>(c) & ~0xFFull) == 0)))];
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
fastfloat_really_inline constexpr uint_fast8_t
|
fastfloat_really_inline constexpr uint_fast8_t
|
||||||
max_digits_u64(uint_fast8_t base) noexcept {
|
max_digits_u64(uint_fast8_t base) noexcept {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user