Open
Description
- 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