diff --git a/src/node_buffer.cc b/src/node_buffer.cc index 6e141b974131cc..bf0bfc70470c8d 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -35,6 +35,7 @@ #include "v8-fast-api-calls.h" #include "v8.h" +#include #include #include #include "nbytes.h" @@ -752,13 +753,35 @@ uint32_t FastByteLengthUtf8(Local receiver, if (source.length > 128) { return simdutf::utf8_length_from_latin1(source.data, source.length); } + uint32_t length = source.length; - uint32_t result = length; - const uint8_t* data = reinterpret_cast(source.data); - for (uint32_t i = 0; i < length; ++i) { - result += (data[i] >> 7); + const auto input = reinterpret_cast(source.data); + + uint32_t answer = length; + uint32_t i = 0; + + for(; i + 32 <= length; i += 32) { + uint64_t v; + memcpy(&v, input + i, 8); + answer += std::popcount(v); + memcpy(&v, input + i + 8, 8); + answer += std::popcount(v); + memcpy(&v, input + i + 16, 8); + answer += std::popcount(v); + memcpy(&v, input + i + 24, 8); + answer += std::popcount(v); + } + for(; i + 8 <= length; i += 8) { + uint64_t v; + memcpy(&v, input + i, sizeof(v)); + answer += std::popcount(v); } - return result; + while (i < length) { + answer += ((uint8_t)input[i] >> 7); + i++; + } + + return answer; } static v8::CFunction fast_byte_length_utf8(