From b97e1f1e833ab296402eef125369168b5474c1ea 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 | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/src/node_buffer.cc b/src/node_buffer.cc index 6e141b974131cc..47ba784656fce1 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, sizeof(v)); + answer += std::popcount(v); + memcpy(&v, input + i + 8, sizeof(v)); + answer += std::popcount(v); + memcpy(&v, input + i + 16, sizeof(v)); + answer += std::popcount(v); + memcpy(&v, input + i + 24, sizeof(v)); + 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(