Skip to content

Conversation

@benjamingr
Copy link
Member

Opening a PR to have the discussion about this particular idea (doc-deprecating buffer.slice).

References: #41588

For the why - buffer.slice() returns a mutable slice whereas typedArray.slice() and array.slice() return a copy. This is confusing behavior and is the result of buffers predating Uint8Array availability.

cc @addaleax @jasnell @sindresorhus @nodejs/buffer

Also ccing some people who are usually helpful at giving useful comments when I make PRs that touch docs: @Trott @aduh95 @VoltrexMaster

@benjamingr benjamingr added buffer Issues and PRs related to the buffer subsystem. deprecations Issues and PRs related to deprecations. labels Jan 19, 2022
@nodejs-github-bot nodejs-github-bot added the doc Issues and PRs related to the documentations. label Jan 19, 2022
@Mesteery
Copy link
Contributor

Mesteery commented Jan 19, 2022

An entry in https://github.com/nodejs/node/blob/master/doc/api/deprecations.md should also be added.

@benjamingr benjamingr force-pushed the doc-deprecate-buffer-slice branch from 482b28b to d1f4857 Compare January 19, 2022 16:44
@benjamingr
Copy link
Member Author

Done, thanks.

@vweevers
Copy link
Contributor

Maybe relevant: I noticed that buffer.subarray() is slower than buffer.slice() (I think it was on node 16.9.1)

@aduh95 aduh95 changed the title buffer: deprecate buffer.slice doc: deprecate buffer.slice Jan 19, 2022
Copy link
Member

@jasnell jasnell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally +1 on this. The one downside is that whenever a Buffer is used transparently as a Uint8Array users could still end up using slice() without realizing that there's a material difference between those. It might make sense eventually to make this a runtime deprecation or emit a warning.

@benjamingr
Copy link
Member Author

benjamingr commented Jan 19, 2022

@aduh95 TIL that issue titles support markdown :O

@vweevers if that is a concern we can override subarray with slice however I think that's surprising looking at the code (it implies new Uint8Array(arr.buffer, byteOffset, length) is measurably faster than arr.subarray(begin, end) (that's basically what the .slice code does).

(Edit, looking at V8 this is subarray https://source.chromium.org/chromium/chromium/src/+/main:v8/src/builtins/typed-array-subarray.tq?q=subarray&ss=chromium%2Fchromium%2Fsrc and here is some of the logic https://source.chromium.org/chromium/chromium/src/+/main:v8/src/builtins/typed-array-subarray.tq?q=subarray&ss=chromium%2Fchromium%2Fsrc if this is a concern we can run benchmarks)

@benjamingr
Copy link
Member Author

@jasnell Ideally I'll follow this up with a runtime warning if --pending-deprecations is run but I think a warning is likely going to be hard to ship (I may be pessimistic) given how omnipresent buffers are.

Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm -1 for this deprecation. buffer.slice() is used kind of everywhere.

@benjamingr benjamingr force-pushed the doc-deprecate-buffer-slice branch from 7365c66 to 79621a5 Compare January 19, 2022 17:08
@aduh95
Copy link
Contributor

aduh95 commented Jan 19, 2022

I believe the subsystem in the commit message should doc: as this is a doc-deprecation.

If proposal-rm-builtin-subclassing ever goes through, buffer.subarray would no longer return a Buffer (it would return a UInt8Array), not sure if this is actually a concern but maybe something to have in mind.

I've also noticed performance regressions when trying to replace .slice calls with primordials.TypedArrayPrototypeSubArray, as if the Node.js slice method takes shortcut that built-in subarray doesn't take, maybe an issue with V8 🤷‍♂️

@mcollina
Copy link
Member

I think .subarry() should have equivalent performance of slice() before deprecating slice().

@addaleax
Copy link
Member

I'm -1 for this deprecation. buffer.slice() is used kind of everywhere.

Which is a good reason not to runtime-deprecate this, but how does the frequency of use affect doc deprecations?

Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM for a doc-deprecation but hard -1 for anything further. We would need to support this forever.

@addaleax
Copy link
Member

I think .subarry() should have equivalent performance of slice() before deprecating slice().

I’m wondering how bad it would be if we did Buffer.prototype.subarray = Buffer.prototype.slice;? I think it would break in the case that Buffer is being subclassed, but that seems to be an edge case that we could get away with breaking.

@benjamingr benjamingr added the blocked PRs that are blocked by other issues or PRs. label Jan 19, 2022
@benjamingr
Copy link
Member Author

Hey, just pre-emptively putting "blocked" on this so we don't land this without checking that the performance doesn't regress with .subarray (and address it if it does) as that concern has been raised by several people (and I also personally agree with it).

I don't think we can ever runtime deprecate it either but we can print a warning with --pending-deprecations (in a follow up) right?

@benjamingr benjamingr force-pushed the doc-deprecate-buffer-slice branch from 9bfde1f to a99e537 Compare January 19, 2022 17:46
@jasnell
Copy link
Member

jasnell commented Jan 19, 2022

I’m wondering how bad it would be if we did Buffer.prototype.subarray = Buffer.prototype.slice;?

Why not flip that... make Buffer.prototype.slice an alias for Buffer.prototype.subarray, and make subarrays implementation the faster one. Attaching the alias to the prototype should address the potential subclass issue.

@addaleax
Copy link
Member

@jasnell Sure, that’s the same thing. It doesn’t really matter whether it’s Buffer.prototype.slice = Buffer.prototype.subarray = function() { ... }; or Buffer.prototype.subarray = Buffer.prototype.slice = function() { ... }; to me.

Copy link
Contributor

@aduh95 aduh95 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Whoever lands this, please update subsystem in the commit messages:

doc: deprecate `buffer.slice`

benchmark: add `subarray` to `buffer-slice`

buffer: alias `subarray` and `slice`

@aduh95 aduh95 added author ready PRs that have at least one approval, no pending requests for changes, and a CI started. semver-minor PRs that contain new features and should be released in the next minor version. labels Jan 21, 2022
@shalvah
Copy link
Contributor

shalvah commented Jan 21, 2022

@benjamingr Made the PR: #41628

@aduh95
Copy link
Contributor

aduh95 commented Jan 21, 2022

Landed in 290911b...3d23d62

@aduh95 aduh95 closed this Jan 21, 2022
@benjamingr benjamingr added notable-change PRs with changes that should be highlighted in changelogs. and removed notable-change PRs with changes that should be highlighted in changelogs. labels Jan 22, 2022
@benjamingr
Copy link
Member Author

@bricss

It's anyway gonna be weird to have at the same time some method deprecated, and not to be deprecated, kinda heisenfeature all the way down 😵‍💫

You mean "Node.js doubles the performance of subarray!"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

author ready PRs that have at least one approval, no pending requests for changes, and a CI started. buffer Issues and PRs related to the buffer subsystem. deprecations Issues and PRs related to deprecations. doc Issues and PRs related to the documentations. semver-minor PRs that contain new features and should be released in the next minor version.

Projects

None yet

Development

Successfully merging this pull request may close these issues.