summaryrefslogtreecommitdiff
path: root/absl/strings/numbers_test.cc
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2022-09-13 18:34:27 -0700
committerGravatar Copybara-Service <copybara-worker@google.com>2022-09-13 18:35:14 -0700
commitdc6109e0c8b2f6ba0fde389050ff6de6c9a082e7 (patch)
treeb1f4f7c4cf7feb61a0c9ed9f68ca2ded4b39ed3b /absl/strings/numbers_test.cc
parent530cd52f585c9d31b2b28cea7e53915af7a878e3 (diff)
Implement Eisel-Lemire for from_chars<double>
Eisel-Lemire is a fast Atod algorithm, discussed at https://nigeltao.github.io/blog/2020/eisel-lemire.html Median of 5 runs of "time atod_manual_test pnftd/data/*.txt" user 0m1.477s # Before user 0m0.746s # After (a speed-up of 1.98x) where pnftd is https://github.com/nigeltao/parse-number-fxx-test-data "benchy --reference=srcfs --benchmark_filter='SimpleAtod' :numbers_benchmark" output (which uses deterministic but randomly generated input strings): name old cpu/op new cpu/op delta BM_SimpleAtod<absl::string_view>/10/1 388ns ± 3% 330ns ± 2% -15.06% (p=0.000 n=49+44) BM_SimpleAtod<absl::string_view>/10/2 428ns ± 3% 320ns ± 2% -25.07% (p=0.000 n=59+49) BM_SimpleAtod<absl::string_view>/10/4 431ns ± 3% 353ns ± 4% -18.04% (p=0.000 n=59+48) BM_SimpleAtod<absl::string_view>/10/8 512ns ± 3% 409ns ± 4% -20.18% (p=0.000 n=60+56) BM_SimpleAtod<const char*>/10/1 411ns ± 4% 341ns ± 3% -17.15% (p=0.000 n=51+49) BM_SimpleAtod<const char*>/10/2 431ns ± 3% 356ns ± 2% -17.44% (p=0.000 n=58+48) BM_SimpleAtod<const char*>/10/4 437ns ± 3% 378ns ± 4% -13.49% (p=0.000 n=60+50) BM_SimpleAtod<const char*>/10/8 552ns ± 2% 450ns ± 4% -18.43% (p=0.000 n=59+59) BM_SimpleAtod<std::string>/10/1 404ns ± 2% 328ns ± 2% -18.78% (p=0.000 n=48+49) BM_SimpleAtod<std::string>/10/2 438ns ± 3% 321ns ± 3% -26.81% (p=0.000 n=60+50) BM_SimpleAtod<std::string>/10/4 446ns ± 2% 354ns ± 3% -20.66% (p=0.000 n=59+50) BM_SimpleAtod<std::string>/10/8 519ns ± 2% 410ns ± 4% -21.07% (p=0.000 n=59+50) sizeof(kPower10MantissaTable) doubles from 5208 to 10416 bytes. PiperOrigin-RevId: 474174891 Change-Id: Iea6f6569419b6b55ab5978994f0adb1f4a8aafb2
Diffstat (limited to 'absl/strings/numbers_test.cc')
-rw-r--r--absl/strings/numbers_test.cc21
1 files changed, 21 insertions, 0 deletions
diff --git a/absl/strings/numbers_test.cc b/absl/strings/numbers_test.cc
index 04e4bd2a..41e95b80 100644
--- a/absl/strings/numbers_test.cc
+++ b/absl/strings/numbers_test.cc
@@ -406,6 +406,19 @@ TEST(NumbersTest, Atod) {
EXPECT_TRUE(absl::SimpleAtod("-INF", &d));
EXPECT_TRUE(std::isinf(d) && (d < 0));
+ // Parse DBL_MAX. Parsing something more than twice as big should also
+ // produce infinity.
+ EXPECT_TRUE(absl::SimpleAtod("1.7976931348623157e+308", &d));
+ EXPECT_EQ(d, 1.7976931348623157e+308);
+ EXPECT_TRUE(absl::SimpleAtod("5e308", &d));
+ EXPECT_TRUE(std::isinf(d) && (d > 0));
+
+ // Parse DBL_MIN (normal) and DBL_TRUE_MIN (subnormal).
+ EXPECT_TRUE(absl::SimpleAtod("2.2250738585072014e-308", &d));
+ EXPECT_EQ(d, 2.2250738585072014e-308);
+ EXPECT_TRUE(absl::SimpleAtod("4.9406564584124654e-324", &d));
+ EXPECT_EQ(d, 4.9406564584124654e-324);
+
// Leading and/or trailing whitespace is OK.
EXPECT_TRUE(absl::SimpleAtod(" \t\r\n 2.718", &d));
EXPECT_EQ(d, 2.718);
@@ -439,6 +452,14 @@ TEST(NumbersTest, Atod) {
EXPECT_TRUE(absl::SimpleAtod("8.9", &d));
EXPECT_FALSE(absl::SimpleAtod("8,9", &d));
+ // These examples are called out in the EiselLemire function's comments.
+ EXPECT_TRUE(absl::SimpleAtod("4503599627370497.5", &d));
+ EXPECT_EQ(d, 4503599627370497.5);
+ EXPECT_TRUE(absl::SimpleAtod("1e+23", &d));
+ EXPECT_EQ(d, 1e+23);
+ EXPECT_TRUE(absl::SimpleAtod("9223372036854775807", &d));
+ EXPECT_EQ(d, 9223372036854775807);
+
// Some parsing algorithms don't always round correctly (but absl::SimpleAtod
// should). This test case comes from
// https://github.com/serde-rs/json/issues/707