From 6e3ab468123c01b0bf3cac9b8fa3b9ba0f2f2a38 Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Mon, 12 Aug 2024 23:10:08 +0200 Subject: [PATCH] buffer: optimize byteLength for short strings PR-URL: https://github.com/nodejs/node/pull/54345 --- src/node_buffer.cc | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/node_buffer.cc b/src/node_buffer.cc index 6e141b974131cc..4dd660f3059325 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,34 @@ 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; + for(; i + 8 <= length; i += 1) { + answer += ((uint8_t)input[i] >> 7); + } + + return answer; } static v8::CFunction fast_byte_length_utf8(