nodejs/node · #62248

src: use simdutf for two-byte string utf8 conversion in utf8 value

mertcanaltin · merged Aug 21, 20262 files · 37 + / 5
benchmark/util/utf8-value.jsadded25 + / 0
@@ -0,0 +1,25 @@+'use strict';++const common = require('../common.js');++const bench = common.createBenchmark(main, {+  type: ['ascii', 'two_bytes', 'three_bytes', 'mixed'],+  n: [5e6],+});++const urls = {+  ascii: 'https://example.com/path/to/resource?query=value&foo=bar',+  two_bytes: 'https://example.com/yol/türkçe/içerik?sağlık=değer',+  three_bytes: 'https://example.com/路径/资源?查询=值&名称=数据',+  mixed: 'https://example.com/hello/世界/path?name=değer&key=数据',+};++function main({ n, type }) {+  const str = urls[type];++  bench.start();+  for (let i = 0; i < n; i++) {+    URL.canParse(str);+  }+  bench.end(n);+}
src/util.cc12 + / 5
@@ -121,13 +121,20 @@ static void MakeUtf8String(Isolate* isolate,     return;   } -  // Add +1 for null termination.-  size_t storage = (3 * value_length) + 1;+  auto const_char16 = reinterpret_cast<const char16_t*>(value_view.data16());+  size_t storage = static_cast<size_t>(value_length) * 3 + 1;   target->AllocateSufficientStorage(storage); -  size_t length = string->WriteUtf8V2(-      isolate, target->out(), storage, String::WriteFlags::kReplaceInvalidUtf8);-  target->SetLengthAndZeroTerminate(length);+  size_t actual_length =+      simdutf::convert_utf16_to_utf8(const_char16, value_length, target->out());+  if (actual_length == 0) {+    actual_length =+        string->WriteUtf8V2(isolate,+                            target->out(),+                            storage,+                            String::WriteFlags::kReplaceInvalidUtf8);+  }+  target->SetLengthAndZeroTerminate(actual_length); }  Utf8Value::Utf8Value(Isolate* isolate, Local<Value> value) {