Skip to content

Commit

Permalink
Slight optimization to parse_int_value_exhaustive_valid
Browse files Browse the repository at this point in the history
  • Loading branch information
eliaskosunen committed Nov 9, 2023
1 parent 06a59f8 commit d55cca7
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 4 deletions.
2 changes: 2 additions & 0 deletions include/scn/external/nanorange/nanorange.hpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// NanoRange WITH MODIFICATION at line 3338

// nanorange.hpp
//
// Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com)
Expand Down
19 changes: 15 additions & 4 deletions src/scn/impl/reader/integer_reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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<int>(n));
value += word;
source = source.substr(n);
}

for (auto ch : source) {
Expand Down

0 comments on commit d55cca7

Please sign in to comment.