From d55cca7a5b0c6f0865b4fbc3ebaa47e0946f8305 Mon Sep 17 00:00:00 2001 From: Elias Kosunen Date: Fri, 10 Nov 2023 01:31:49 +0200 Subject: [PATCH] Slight optimization to parse_int_value_exhaustive_valid --- include/scn/external/nanorange/nanorange.hpp | 2 ++ src/scn/impl/reader/integer_reader.cpp | 19 +++++++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/include/scn/external/nanorange/nanorange.hpp b/include/scn/external/nanorange/nanorange.hpp index ccbdac4a..9ef6f184 100644 --- a/include/scn/external/nanorange/nanorange.hpp +++ b/include/scn/external/nanorange/nanorange.hpp @@ -1,3 +1,5 @@ +// NanoRange WITH MODIFICATION at line 3338 + // nanorange.hpp // // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) diff --git a/src/scn/impl/reader/integer_reader.cpp b/src/scn/impl/reader/integer_reader.cpp index d3747f43..80492bfb 100644 --- a/src/scn/impl/reader/integer_reader.cpp +++ b/src/scn/impl/reader/integer_reader.cpp @@ -498,16 +498,26 @@ namespace scn { SCN_EXPECT(!source.empty()); SCN_EXPECT(numeric_reader_base::char_to_int(source.front()) < 10); - for (; source.size() >= 8; source = source.substr(8)) { + while (source.size() >= 4) { + const auto n = std::min(source.size(), size_t{8}); uint64_t word{}; - std::memcpy(&word, source.data(), 8); + std::memcpy(&word, source.data(), n); - for (char ch : source.substr(0, 8)) { +#ifndef NDEBUG + for (char ch : source.substr(0, n)) { SCN_EXPECT(numeric_reader_base::char_to_int(ch) < 10); } +#endif // See above, do_read_decimal_fast64 + if (n != 8) { + const uint64_t shift = 8 * (8 - n); + word <<= shift; + const uint64_t mask = (~0ull) << shift; + word = (mask & word) | (~mask & 0x3030303030303030ull); + } + constexpr uint64_t mask = 0x000000FF000000FFull; constexpr uint64_t mul1 = 100 + (1000000ull << 32); constexpr uint64_t mul2 = 1 + (10000ull << 32); @@ -518,8 +528,9 @@ namespace scn { (((word & mask) * mul1) + (((word >> 16) & mask) * mul2)) >> 32; - value *= power_of_10(8); + value *= power_of_10(static_cast(n)); value += word; + source = source.substr(n); } for (auto ch : source) {