Skip to content

Commit 1207719

Browse files
committed
util: improve textdecoder decode performance
1 parent f1e9382 commit 1207719

File tree

3 files changed

+46
-10
lines changed

3 files changed

+46
-10
lines changed

benchmark/util/text-decoder.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
'use strict';
2+
3+
const common = require('../common.js');
4+
5+
const bench = common.createBenchmark(main, {
6+
len: [1, 64, 1024],
7+
n: [1e6]
8+
});
9+
10+
function main({ len, n }) {
11+
const buf = Buffer.alloc(len, 42);
12+
const decoder = new TextDecoder();
13+
14+
bench.start();
15+
decoder.decode(buf);
16+
bench.end(n);
17+
}

lib/internal/encoding.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ function makeTextDecoderICU() {
432432
if (typeof ret === 'number') {
433433
throw new ERR_ENCODING_INVALID_ENCODED_DATA(this.encoding, ret);
434434
}
435-
return ret.toString('ucs2');
435+
return ret;
436436
}
437437
}
438438

src/node_i18n.cc

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050
#include "node_buffer.h"
5151
#include "node_errors.h"
5252
#include "node_internals.h"
53+
#include "string_bytes.h"
54+
#include "string_decoder.h"
5355
#include "util-inl.h"
5456
#include "v8.h"
5557

@@ -502,18 +504,35 @@ void ConverterObject::Decode(const FunctionCallbackInfo<Value>& args) {
502504
}
503505
}
504506
ret = ToBufferEndian(env, &result);
505-
if (omit_initial_bom && !ret.IsEmpty()) {
506-
// Perform `ret = ret.slice(2)`.
507+
508+
if (!ret.IsEmpty()) {
507509
CHECK(ret.ToLocalChecked()->IsUint8Array());
508-
Local<Uint8Array> orig_ret = ret.ToLocalChecked().As<Uint8Array>();
509-
ret = Buffer::New(env,
510-
orig_ret->Buffer(),
511-
orig_ret->ByteOffset() + 2,
512-
orig_ret->ByteLength() - 2)
510+
511+
if (omit_initial_bom) {
512+
// Perform `ret = ret.slice(2)`.
513+
Local<Uint8Array> orig_ret = ret.ToLocalChecked().As<Uint8Array>();
514+
ret = Buffer::New(env,
515+
orig_ret->Buffer(),
516+
orig_ret->ByteOffset() + 2,
517+
orig_ret->ByteLength() - 2)
513518
.FromMaybe(Local<Uint8Array>());
519+
}
520+
521+
Local<Value> error;
522+
ArrayBufferViewContents<char> buf(ret.ToLocalChecked());
523+
MaybeLocal<Value> encoded = StringBytes::Encode(env->isolate(),
524+
buf.data(),
525+
buf.length(),
526+
encoding::UCS2,
527+
&error);
528+
529+
if (!encoded.IsEmpty()) {
530+
args.GetReturnValue().Set(encoded.ToLocalChecked());
531+
} else {
532+
args.GetReturnValue().Set(error);
533+
}
514534
}
515-
if (!ret.IsEmpty())
516-
args.GetReturnValue().Set(ret.ToLocalChecked());
535+
517536
return;
518537
}
519538

0 commit comments

Comments
 (0)