nodejs/node · #62248
src: use simdutf for two-byte string utf8 conversion in utf8 value
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) {