Skip to content

Commit

Permalink
Use fast_float for folly string to float conversions
Browse files Browse the repository at this point in the history
Summary:
This uses the fast_float library for folly's string to float conversions instead of double-conversion.

It is enabled by removing the condition that would switch between using fast_float and double-conversion. This also removes the dead double-conversion string to float conversion function and the dead buck configuration option.

Reviewed By: Gownta

Differential Revision: D65233579

fbshipit-source-id: 5a597dac3682f9c6c60387393ea0c8005eb07423
  • Loading branch information
skrueger authored and facebook-github-bot committed Nov 1, 2024
1 parent b67cd36 commit 2f646af
Show file tree
Hide file tree
Showing 3 changed files with 0 additions and 140 deletions.
6 changes: 0 additions & 6 deletions folly/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -265,12 +265,6 @@ cpp_library(
"-DFOLLY_CONV_DTOA_TO_CHARS=1",
],
"DEFAULT": [],
}) + select({
"//folly/buck_config:folly-conv-atod-mode-fastfloat": [
# Use fast_float::from_chars for ASCII-to-Double conversions
"-DFOLLY_CONV_ATOD_MODE=1",
],
"DEFAULT": [],
}),
undefined_symbols = True, # TODO(T23121628): fix deps and remove
deps = [
Expand Down
124 changes: 0 additions & 124 deletions folly/Conv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -342,126 +342,6 @@ Expected<bool, ConversionCode> str_to_bool(StringPiece* src) noexcept {
return result;
}

/// Uses `double_conversion` library to convert from string to a floating
/// point.
template <class Tgt>
Expected<Tgt, ConversionCode> str_to_floating_double_conversion(
StringPiece* src) noexcept {
using namespace double_conversion;
static StringToDoubleConverter conv(
StringToDoubleConverter::ALLOW_TRAILING_JUNK |
StringToDoubleConverter::ALLOW_LEADING_SPACES,
0.0,
// return this for junk input string
std::numeric_limits<Tgt>::quiet_NaN(),
nullptr,
nullptr);

if (src->empty()) {
return makeUnexpected(ConversionCode::EMPTY_INPUT_STRING);
}

int length; // processed char count
auto result = std::is_same<Tgt, float>::value
? conv.StringToFloat(src->data(), static_cast<int>(src->size()), &length)
: static_cast<Tgt>(conv.StringToDouble(
src->data(), static_cast<int>(src->size()), &length));

if (!std::isnan(result)) {
// If we get here with length = 0, the input string is empty.
// If we get here with result = 0.0, it's either because the string
// contained only whitespace, or because we had an actual zero value
// (with potential trailing junk). If it was only whitespace, we
// want to raise an error; length will point past the last character
// that was processed, so we need to check if that character was
// whitespace or not.
if (length == 0 ||
(result == 0.0 && std::isspace((*src)[size_t(length) - 1]))) {
return makeUnexpected(ConversionCode::EMPTY_INPUT_STRING);
}
if (length >= 2) {
const char* suffix = src->data() + length - 1;
// double_conversion doesn't update length correctly when there is an
// incomplete exponent specifier. Converting "12e-f-g" shouldn't consume
// any more than "12", but it will consume "12e-".

// "123-" should only parse "123"
if (*suffix == '-' || *suffix == '+') {
--suffix;
--length;
}
// "12e-f-g" or "12euro" should only parse "12"
if (*suffix == 'e' || *suffix == 'E') {
--length;
}
}
src->advance(size_t(length));
return Tgt(result);
}

auto* e = src->end();
auto* b = std::find_if_not(src->begin(), e, [](char c) {
return (c >= '\t' && c <= '\r') || c == ' ';
});
if (b == e) {
return makeUnexpected(ConversionCode::EMPTY_INPUT_STRING);
}
auto size = size_t(e - b);

bool negative = false;
if (*b == '-') {
negative = true;
++b;
--size;
if (size == 0) {
return makeUnexpected(ConversionCode::STRING_TO_FLOAT_ERROR);
}
}
assert(size > 0);

result = 0.0;

switch (tolower_ascii(*b)) {
case 'i':
if (size >= 3 && tolower_ascii(b[1]) == 'n' &&
tolower_ascii(b[2]) == 'f') {
if (size >= 8 && tolower_ascii(b[3]) == 'i' &&
tolower_ascii(b[4]) == 'n' && tolower_ascii(b[5]) == 'i' &&
tolower_ascii(b[6]) == 't' && tolower_ascii(b[7]) == 'y') {
b += 8;
} else {
b += 3;
}
result = std::numeric_limits<Tgt>::infinity();
}
break;

case 'n':
if (size >= 3 && tolower_ascii(b[1]) == 'a' &&
tolower_ascii(b[2]) == 'n') {
b += 3;
result = std::numeric_limits<Tgt>::quiet_NaN();
}
break;

default:
break;
}

if (result == 0.0) {
// All bets are off
return makeUnexpected(ConversionCode::STRING_TO_FLOAT_ERROR);
}

if (negative) {
result = -result;
}

src->assign(b, e);

return Tgt(result);
}

/// Uses `fast_float::from_chars` to convert from string to an integer.
template <class Tgt>
Expected<Tgt, ConversionCode> str_to_floating_fast_float_from_chars(
Expand Down Expand Up @@ -512,11 +392,7 @@ str_to_floating_fast_float_from_chars<double>(StringPiece* src) noexcept;
*/
template <class Tgt>
Expected<Tgt, ConversionCode> str_to_floating(StringPiece* src) noexcept {
#if defined(FOLLY_CONV_ATOD_MODE) && FOLLY_CONV_ATOD_MODE == 1
return detail::str_to_floating_fast_float_from_chars<Tgt>(src);
#else
return detail::str_to_floating_double_conversion<Tgt>(src);
#endif
}

template Expected<float, ConversionCode> str_to_floating<float>(
Expand Down
10 changes: 0 additions & 10 deletions folly/buck_config/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,3 @@ fb_native.config_setting(
},
visibility = ["PUBLIC"],
)

# Config setting to change the implementation of folly::detail::str_to_float
# to use fast_float::from_chars
fb_native.config_setting(
name = "folly-conv-atod-mode-fastfloat",
values = {
"folly.conv_atod_mode": "fastfloat",
},
visibility = ["PUBLIC"],
)

0 comments on commit 2f646af

Please sign in to comment.