From 5292a1358f834d4788ab10dbe83bf5ea2d35a54d Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Fri, 20 May 2016 10:50:53 +0100 Subject: buffer: improve creation performance. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Improves performance of allocating unsafe buffers, creating buffers from an existing ArrayBuffer and creating .slice(...) from existing Buffer by avoiding deoptimizing change of prototype after Uint8Array allocation in favor of ES6 native subclassing. This is done through an internal ES6 class that extends Uint8Array and is used for allocations, but the regular Buffer function is exposed, so calling Buffer(...) with or without `new` continues to work as usual and prototype chains are also preserved. Performance wins for .slice are +120% (2.2x), and, consequently, for unsafe allocations up to +95% (1.9x) for small buffers, and for safe allocations (zero-filled) up to +30% (1.3x). PR-URL: https://github.com/nodejs/node/pull/6893 Reviewed-By: Anna Henningsen Reviewed-By: Сковорода Никита Андреевич --- src/node_buffer.cc | 28 ---------------------------- 1 file changed, 28 deletions(-) (limited to 'src/node_buffer.cc') diff --git a/src/node_buffer.cc b/src/node_buffer.cc index b8accf517c..388decac4a 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -427,33 +427,6 @@ void CreateFromString(const FunctionCallbackInfo& args) { } -void CreateFromArrayBuffer(const FunctionCallbackInfo& args) { - Environment* env = Environment::GetCurrent(args); - if (!args[0]->IsArrayBuffer()) - return env->ThrowTypeError("argument is not an ArrayBuffer"); - Local ab = args[0].As(); - - size_t ab_length = ab->ByteLength(); - size_t offset; - size_t max_length; - - CHECK_NOT_OOB(ParseArrayIndex(args[1], 0, &offset)); - CHECK_NOT_OOB(ParseArrayIndex(args[2], ab_length - offset, &max_length)); - - if (offset >= ab_length) - return env->ThrowRangeError("'offset' is out of bounds"); - if (max_length > ab_length - offset) - return env->ThrowRangeError("'length' is out of bounds"); - - Local ui = Uint8Array::New(ab, offset, max_length); - Maybe mb = - ui->SetPrototype(env->context(), env->buffer_prototype_object()); - if (!mb.FromMaybe(false)) - return env->ThrowError("Unable to set Object prototype"); - args.GetReturnValue().Set(ui); -} - - template void StringSlice(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); @@ -1244,7 +1217,6 @@ void Initialize(Local target, env->SetMethod(target, "setupBufferJS", SetupBufferJS); env->SetMethod(target, "createFromString", CreateFromString); - env->SetMethod(target, "createFromArrayBuffer", CreateFromArrayBuffer); env->SetMethod(target, "byteLengthUtf8", ByteLengthUtf8); env->SetMethod(target, "compare", Compare); -- cgit v1.2.3