17

I have a look at the Node.js Buffer documentation and I don't understand the difference between Buffer.slice and Buffer.subarray.

Both point to "the same memory as the original".

But no one seems not to be the alias of the other (it seems to be said when it is the case).

And test says that behavior is the same :

> buf=Buffer.from([0,1,2,3,4,5,6])
<Buffer 00 01 02 03 04 05 06>
> bufSlice=buf.slice(1,5)
<Buffer 01 02 03 04>
> bufSub=buf.subarray(1,5)
<Buffer 01 02 03 04>
> bufSlice
<Buffer 01 02 03 04>
> bufSub
<Buffer 01 02 03 04>
> buf[3]=0xff
255
> buf
<Buffer 00 01 02 ff 04 05 06>
> bufSub
<Buffer 01 02 ff 04>
> bufSlice
<Buffer 01 02 ff 04>

(even if example of slice in Node.js documentation is not very clear).

So what's the difference ?

2
  • 1
    I'm not sure, but here is an interesting read on performance between the 2: https://github.com/nodejs/node/issues/17431. It seems they achieve the same results; they are destructive methods that change the memory address values, but their implementations differ because their prototype is Uint8Array.prototype.slice() and TypedArray.prototype.subarray() Commented Jul 29, 2020 at 22:01
  • According to this blog post only the subArray method is referencing to the same chunk in memory. Commented Jun 17, 2022 at 12:33

3 Answers 3

8

For a NodeJS Buffer there is no difference and indeed Buffer.slice() is deprecated now so you should use Buffer.subarray().

This deprecation was presumably done because NodeJS Buffer.slice() was inconsistent with other slice calls in JS, e.g.:

const t = Buffer.from([1])
t.slice()[0]=2
console.log(t[0]) // logs 2, i.e. `slice` uses same underlying memory, like `subarray` does

const t2 = [1]
t2.slice()[0]=2
console.log(t2[0]) // logs 1, unchanged! I.e. `slice` copied underlying memory

const t3 = new Uint8Array([1])
t3.slice()[0]=2
console.log(t3[0]) // logs 1, unchanged! I.e. `slice` copied underlying memory
Sign up to request clarification or add additional context in comments.

4 Comments

my example tells both are references.
hope my edit cleared things up
I guess they didnt want to change Buffer.prototype.slice()'s behavior to bring it in line since that would be surprising and break a ton of stuff. But now we're left with no simple way to easily slice (as a copy) a buffer. Not ideal. I mean Buffer.from() etc. isn't terrible, but it makes the language a tad worse.
You actually can see in the Node.JS source code that slice just calls subarray: github.com/nodejs/node/blob/…
7

Buffer.slice is now deprecated (since node 16.x LTS)

So now use Buffer.subarray !

1 Comment

That doesn't really answer the question whether subarray is the same or not as slice in terms of functionality.
-1

According to https://nodejs.org/api/buffer.html#bufsubarraystart-end, and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice,

Buffer.subarray() is a buffer view that does not need to create an extra copy of the underlying buffer. This makes subarray() much more efficient than slice(), which does create a copy.

1 Comment

According to nodejs.org/api/buffer.html#bufslicestart-end: "This method is not compatible with the Uint8Array.prototype.slice(), which is a superclass of Buffer. To copy the slice, use Uint8Array.prototype.slice()." So Buffer.slice() does not behave like the link to TypedArray.slice()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.