Skip to content

Commit a9817fc

Browse files
committed
use IsOneByte & IsExternalOneByte path for regresion
1 parent c63b474 commit a9817fc

1 file changed

Lines changed: 29 additions & 13 deletions

File tree

src/node_buffer.cc

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -771,18 +771,23 @@ void SlowByteLengthUtf8(const FunctionCallbackInfo<Value>& args) {
771771
return;
772772
}
773773

774+
size_t utf8_length;
775+
776+
// Fast path for external one-byte strings (common case for ASCII/Latin1)
777+
if (source->IsExternalOneByte()) {
778+
auto ext = source->GetExternalOneByteStringResource();
779+
utf8_length = simdutf::utf8_length_from_latin1(ext->data(), ext->length());
780+
args.GetReturnValue().Set(static_cast<uint64_t>(utf8_length));
781+
return;
782+
}
783+
784+
// For non-external strings, use ValueView
774785
String::ValueView view(isolate, source);
775786
size_t length = view.length();
776-
size_t utf8_length;
777787

778788
if (view.is_one_byte()) {
779789
auto data = reinterpret_cast<const char*>(view.data8());
780-
simdutf::result result = simdutf::validate_ascii_with_errors(data, length);
781-
if (result.error == simdutf::SUCCESS) {
782-
utf8_length = length; // Pure ASCII, length stays the same
783-
} else {
784-
utf8_length = simdutf::utf8_length_from_latin1(data, length);
785-
}
790+
utf8_length = simdutf::utf8_length_from_latin1(data, length);
786791
} else {
787792
auto data = reinterpret_cast<const char16_t*>(view.data16());
788793
if (simdutf::validate_utf16(data, length)) {
@@ -805,21 +810,32 @@ uint32_t FastByteLengthUtf8(
805810
CHECK(sourceValue->IsString());
806811
Local<String> sourceStr = sourceValue.As<String>();
807812

813+
int length = sourceStr->Length();
814+
808815
// For short inputs, use V8's path - function call overhead not worth it
809816
static constexpr int kSmallStringThreshold = 128;
810-
if (sourceStr->Length() <= kSmallStringThreshold) {
817+
if (length <= kSmallStringThreshold) {
818+
return sourceStr->Utf8LengthV2(isolate);
819+
}
820+
821+
// Fast path for external one-byte strings (common case for ASCII/Latin1)
822+
if (sourceStr->IsExternalOneByte()) {
823+
auto ext = sourceStr->GetExternalOneByteStringResource();
824+
return simdutf::utf8_length_from_latin1(ext->data(), ext->length());
825+
}
826+
827+
// For one-byte (Latin1/ASCII) strings, V8 is already fast and ValueView
828+
// creation has overhead. Use higher threshold before switching to simdutf.
829+
static constexpr int kOneByteLargeThreshold = 1024;
830+
if (sourceStr->IsOneByte() && length <= kOneByteLargeThreshold) {
811831
return sourceStr->Utf8LengthV2(isolate);
812832
}
813833

834+
// For larger strings or two-byte strings, use ValueView + simdutf
814835
String::ValueView view(isolate, sourceStr);
815-
size_t length = view.length();
816836

817837
if (view.is_one_byte()) {
818838
auto data = reinterpret_cast<const char*>(view.data8());
819-
simdutf::result result = simdutf::validate_ascii_with_errors(data, length);
820-
if (result.error == simdutf::SUCCESS) {
821-
return length; // Pure ASCII, length stays the same
822-
}
823839
return simdutf::utf8_length_from_latin1(data, length);
824840
}
825841

0 commit comments

Comments
 (0)