aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow/core/lib/strings/numbers.cc
diff options
context:
space:
mode:
authorGravatar akindyakov <akindyakov@gmail.com>2018-04-20 11:23:15 -0700
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2018-04-20 11:25:53 -0700
commit570d90b9c7e6a19bc2606fdaf7ad0f85b8590c0e (patch)
treeae3617cdb70686297ddf6bab05d99fd44bb64224 /tensorflow/core/lib/strings/numbers.cc
parent49f3469d9533cb12d06ed3907b4ced975e2fcea4 (diff)
Speed up safe_strtod and safe_strtof functions by using double-conversion library
Closes #12102. PiperOrigin-RevId: 193696537
Diffstat (limited to 'tensorflow/core/lib/strings/numbers.cc')
-rw-r--r--tensorflow/core/lib/strings/numbers.cc51
1 files changed, 35 insertions, 16 deletions
diff --git a/tensorflow/core/lib/strings/numbers.cc b/tensorflow/core/lib/strings/numbers.cc
index c296daa95d..e4b909296e 100644
--- a/tensorflow/core/lib/strings/numbers.cc
+++ b/tensorflow/core/lib/strings/numbers.cc
@@ -23,6 +23,8 @@ limitations under the License.
#include <locale>
#include <unordered_map>
+#include "double-conversion/double-conversion.h"
+
#include "tensorflow/core/lib/strings/str_util.h"
#include "tensorflow/core/lib/strings/stringprintf.h"
#include "tensorflow/core/platform/logging.h"
@@ -110,6 +112,17 @@ T locale_independent_strtonum(const char* str, const char** endptr) {
return result;
}
+static inline const double_conversion::StringToDoubleConverter&
+StringToFloatConverter() {
+ static const double_conversion::StringToDoubleConverter converter(
+ double_conversion::StringToDoubleConverter::ALLOW_LEADING_SPACES |
+ double_conversion::StringToDoubleConverter::ALLOW_HEX |
+ double_conversion::StringToDoubleConverter::ALLOW_TRAILING_SPACES |
+ double_conversion::StringToDoubleConverter::ALLOW_CASE_INSENSIBILITY,
+ 0., 0., "inf", "nan");
+ return converter;
+}
+
} // namespace
namespace strings {
@@ -319,25 +332,31 @@ bool safe_strtou32(StringPiece str, uint32* value) {
}
bool safe_strtof(const char* str, float* value) {
- const char* endptr;
- *value = locale_independent_strtonum<float>(str, &endptr);
- while (isspace(*endptr)) ++endptr;
- // Ignore range errors from strtod/strtof.
- // The values it returns on underflow and
- // overflow are the right fallback in a
- // robust setting.
- return *str != '\0' && *endptr == '\0';
+ int processed_characters_count = -1;
+ auto len = str_util::Strnlen(str, kFastToBufferSize);
+
+ // If there is no zero-termination in str, fail.
+ if (len == kFastToBufferSize) return false;
+ // If string length exceeds int max, fail.
+ if (len > std::numeric_limits<int>::max()) return false;
+
+ *value = StringToFloatConverter().StringToFloat(str, static_cast<int>(len),
+ &processed_characters_count);
+ return processed_characters_count > 0;
}
bool safe_strtod(const char* str, double* value) {
- const char* endptr;
- *value = locale_independent_strtonum<double>(str, &endptr);
- while (isspace(*endptr)) ++endptr;
- // Ignore range errors from strtod/strtof.
- // The values it returns on underflow and
- // overflow are the right fallback in a
- // robust setting.
- return *str != '\0' && *endptr == '\0';
+ int processed_characters_count = -1;
+ auto len = str_util::Strnlen(str, kFastToBufferSize);
+
+ // If there is no zero-termination in str, fail.
+ if (len == kFastToBufferSize) return false;
+ // If string length exceeds int max, fail.
+ if (len > std::numeric_limits<int>::max()) return false;
+
+ *value = StringToFloatConverter().StringToDouble(str, static_cast<int>(len),
+ &processed_characters_count);
+ return processed_characters_count > 0;
}
size_t FloatToBuffer(float value, char* buffer) {