Skip to content

Use %TypedArray%.prototype.subarray for Buffer.prototype.slice #17431

Open
@TimothyGu

Description

@TimothyGu
  • Version: master
  • Platform: all
  • Subsystem: buffer

Currently, our implementation of Buffer.prototype.slice() operates identically to TypedArray.prototype.subarray() (spec) down to the last minutia (with the assumption that this is indeed a Buffer, and Buffer[Symbol.species] has not been tampered with). Ideally, we should just set Buffer.prototype.slice to Uint8Array.prototype.subarray instead of reimplementing it. The only problem is performance: subarray() is much slower than slice():

diff
diff --git a/lib/buffer.js b/lib/buffer.js
index b56c032f9e..112dc22d69 100644
--- a/lib/buffer.js
+++ b/lib/buffer.js
@@ -989,29 +989,7 @@ Buffer.prototype.toJSON = function toJSON() {
 };
 
 
-function adjustOffset(offset, length) {
-  // Use Math.trunc() to convert offset to an integer value that can be larger
-  // than an Int32. Hence, don't use offset | 0 or similar techniques.
-  offset = Math.trunc(offset);
-  // `x !== x`-style conditionals are a faster form of `isNaN(x)`
-  if (offset === 0 || offset !== offset) {
-    return 0;
-  } else if (offset < 0) {
-    offset += length;
-    return offset > 0 ? offset : 0;
-  } else {
-    return offset < length ? offset : length;
-  }
-}
-
-
-Buffer.prototype.slice = function slice(start, end) {
-  const srcLength = this.length;
-  start = adjustOffset(start, srcLength);
-  end = end !== undefined ? adjustOffset(end, srcLength) : srcLength;
-  const newLength = end > start ? end - start : 0;
-  return new FastBuffer(this.buffer, this.byteOffset + start, newLength);
-};
+Buffer.prototype.slice = Uint8Array.prototype.subarray;
 
 
 function checkOffset(offset, ext, length) {
$ ./node-master benchmark/buffers/buffer-slice.js 
buffers/buffer-slice.js n=1024 type="fast": 11,632.49754936561
buffers/buffer-slice.js n=1024 type="slow": 11,584.90297078093
$ ./node benchmark/buffers/buffer-slice.js 
buffers/buffer-slice.js n=1024 type="fast": 6,675.602412489698
buffers/buffer-slice.js n=1024 type="slow": 6,487.594815897296

I'd like to work with the V8 team to resolve the performance problem, and eventually use the language built-in for Buffer.prototype.slice.

/cc @bmeurer

Metadata

Metadata

Assignees

No one assigned

    Labels

    bufferIssues and PRs related to the buffer subsystem.performanceIssues and PRs related to the performance of Node.js.v8 engineIssues and PRs related to the V8 dependency.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions