Skip to content

Commit b80da2f

Browse files
ronagtargos
authored andcommitted
buffer: optimize createFromString
PR-URL: #54324 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
1 parent c5180e9 commit b80da2f

File tree

2 files changed

+29
-31
lines changed

2 files changed

+29
-31
lines changed

lib/buffer.js

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ const {
5757
byteLengthUtf8,
5858
compare: _compare,
5959
compareOffset,
60-
createFromString,
6160
fill: bindingFill,
6261
isAscii: bindingIsAscii,
6362
isUtf8: bindingIsUtf8,
@@ -148,11 +147,12 @@ const constants = ObjectDefineProperties({}, {
148147
});
149148

150149
Buffer.poolSize = 8 * 1024;
151-
let poolSize, poolOffset, allocPool;
150+
let poolSize, poolOffset, allocPool, allocBuffer;
152151

153152
function createPool() {
154153
poolSize = Buffer.poolSize;
155-
allocPool = createUnsafeBuffer(poolSize).buffer;
154+
allocBuffer = createUnsafeBuffer(poolSize);
155+
allocPool = allocBuffer.buffer;
156156
markAsUntransferable(allocPool);
157157
poolOffset = 0;
158158
}
@@ -440,38 +440,49 @@ function allocate(size) {
440440
}
441441

442442
function fromStringFast(string, ops) {
443-
const length = ops.byteLength(string);
443+
const maxLength = Buffer.poolSize >>> 1;
444444

445-
if (length >= (Buffer.poolSize >>> 1))
446-
return createFromString(string, ops.encodingVal);
445+
let length = string.length; // Min length
446+
447+
if (length >= maxLength)
448+
return createFromString(string, ops);
449+
450+
length *= 4; // Max length (4 bytes per character)
451+
452+
if (length >= maxLength)
453+
length = ops.byteLength(string); // Actual length
454+
455+
if (length >= maxLength)
456+
return createFromString(string, ops, length);
447457

448458
if (length > (poolSize - poolOffset))
449459
createPool();
450-
let b = new FastBuffer(allocPool, poolOffset, length);
451-
const actual = ops.write(b, string, 0, length);
452-
if (actual !== length) {
453-
// byteLength() may overestimate. That's a rare case, though.
454-
b = new FastBuffer(allocPool, poolOffset, actual);
455-
}
460+
461+
const actual = ops.write(allocBuffer, string, poolOffset, length);
462+
const b = new FastBuffer(allocPool, poolOffset, actual);
463+
456464
poolOffset += actual;
457465
alignPool();
458466
return b;
459467
}
460468

469+
function createFromString(string, ops, length = ops.byteLength(string)) {
470+
const buf = Buffer.allocUnsafeSlow(length);
471+
const actual = ops.write(buf, string, 0, length);
472+
return actual < length ? new FastBuffer(buf.buffer, 0, actual) : buf;
473+
}
474+
461475
function fromString(string, encoding) {
462476
let ops;
463-
if (typeof encoding !== 'string' || encoding.length === 0) {
464-
if (string.length === 0)
465-
return new FastBuffer();
477+
if (!encoding || encoding === 'utf8') {
466478
ops = encodingOps.utf8;
467479
} else {
468480
ops = getEncodingOps(encoding);
469481
if (ops === undefined)
470482
throw new ERR_UNKNOWN_ENCODING(encoding);
471-
if (string.length === 0)
472-
return new FastBuffer();
473483
}
474-
return fromStringFast(string, ops);
484+
485+
return string.length === 0 ? new FastBuffer() : fromStringFast(string, ops);
475486
}
476487

477488
function fromArrayBuffer(obj, byteOffset, length) {

src/node_buffer.cc

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -529,17 +529,6 @@ MaybeLocal<Object> New(Environment* env,
529529

530530
namespace {
531531

532-
void CreateFromString(const FunctionCallbackInfo<Value>& args) {
533-
CHECK(args[0]->IsString());
534-
CHECK(args[1]->IsInt32());
535-
536-
enum encoding enc = static_cast<enum encoding>(args[1].As<Int32>()->Value());
537-
Local<Object> buf;
538-
if (New(args.GetIsolate(), args[0].As<String>(), enc).ToLocal(&buf))
539-
args.GetReturnValue().Set(buf);
540-
}
541-
542-
543532
template <encoding encoding>
544533
void StringSlice(const FunctionCallbackInfo<Value>& args) {
545534
Environment* env = Environment::GetCurrent(args);
@@ -1422,7 +1411,6 @@ void Initialize(Local<Object> target,
14221411
SetMethodNoSideEffect(context, target, "btoa", Btoa);
14231412

14241413
SetMethod(context, target, "setBufferPrototype", SetBufferPrototype);
1425-
SetMethodNoSideEffect(context, target, "createFromString", CreateFromString);
14261414

14271415
SetFastMethodNoSideEffect(context,
14281416
target,
@@ -1487,7 +1475,6 @@ void Initialize(Local<Object> target,
14871475

14881476
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
14891477
registry->Register(SetBufferPrototype);
1490-
registry->Register(CreateFromString);
14911478

14921479
registry->Register(SlowByteLengthUtf8);
14931480
registry->Register(fast_byte_length_utf8.GetTypeInfo());

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy