-
-
Notifications
You must be signed in to change notification settings - Fork 35.2k
buffer: improve performance of multiple Buffer operations #61871
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
1ec8a92
9c66a0a
631ec7d
ef4dd77
4d2f539
6e9f17d
2a67802
2cdc20a
49e79cc
7c8b68d
85fb7f1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| 'use strict'; | ||
|
|
||
| const common = require('../common.js'); | ||
|
|
||
| const bench = common.createBenchmark(main, { | ||
| type: ['Uint8Array', 'Uint16Array', 'Uint32Array', 'Float64Array'], | ||
| len: [64, 256, 2048], | ||
| partial: ['none', 'offset', 'offset-length'], | ||
| n: [6e5], | ||
| }); | ||
|
|
||
| function main({ n, len, type, partial }) { | ||
| const TypedArrayCtor = globalThis[type]; | ||
| const src = new TypedArrayCtor(len); | ||
| for (let i = 0; i < len; i++) src[i] = i; | ||
|
|
||
| let offset; | ||
| let length; | ||
| if (partial === 'offset') { | ||
| offset = len >>> 2; | ||
| } else if (partial === 'offset-length') { | ||
| offset = len >>> 2; | ||
| length = len >>> 1; | ||
| } | ||
|
|
||
| bench.start(); | ||
| for (let i = 0; i < n; i++) { | ||
| Buffer.copyBytesFrom(src, offset, length); | ||
| } | ||
| bench.end(n); | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -50,7 +50,6 @@ const { | |||||||||||||||||||||||||||||||||||||
| TypedArrayPrototypeGetByteOffset, | ||||||||||||||||||||||||||||||||||||||
| TypedArrayPrototypeGetLength, | ||||||||||||||||||||||||||||||||||||||
| TypedArrayPrototypeSet, | ||||||||||||||||||||||||||||||||||||||
| TypedArrayPrototypeSlice, | ||||||||||||||||||||||||||||||||||||||
| TypedArrayPrototypeSubarray, | ||||||||||||||||||||||||||||||||||||||
| Uint8Array, | ||||||||||||||||||||||||||||||||||||||
| } = primordials; | ||||||||||||||||||||||||||||||||||||||
|
|
@@ -383,28 +382,33 @@ Buffer.copyBytesFrom = function copyBytesFrom(view, offset, length) { | |||||||||||||||||||||||||||||||||||||
| return new FastBuffer(); | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| if (offset !== undefined || length !== undefined) { | ||||||||||||||||||||||||||||||||||||||
| if (offset !== undefined) { | ||||||||||||||||||||||||||||||||||||||
| validateInteger(offset, 'offset', 0); | ||||||||||||||||||||||||||||||||||||||
| if (offset >= viewLength) return new FastBuffer(); | ||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||
| offset = 0; | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
| let end; | ||||||||||||||||||||||||||||||||||||||
| if (length !== undefined) { | ||||||||||||||||||||||||||||||||||||||
| validateInteger(length, 'length', 0); | ||||||||||||||||||||||||||||||||||||||
| end = offset + length; | ||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||
| end = viewLength; | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
| let start = 0; | ||||||||||||||||||||||||||||||||||||||
| let end = viewLength; | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| view = TypedArrayPrototypeSlice(view, offset, end); | ||||||||||||||||||||||||||||||||||||||
| if (offset !== undefined) { | ||||||||||||||||||||||||||||||||||||||
| validateInteger(offset, 'offset', 0); | ||||||||||||||||||||||||||||||||||||||
| if (offset >= viewLength) return new FastBuffer(); | ||||||||||||||||||||||||||||||||||||||
| start = offset; | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| if (length !== undefined) { | ||||||||||||||||||||||||||||||||||||||
| validateInteger(length, 'length', 0); | ||||||||||||||||||||||||||||||||||||||
| // The old code used TypedArrayPrototypeSlice which clamps internally. | ||||||||||||||||||||||||||||||||||||||
| end = MathMin(start + length, viewLength); | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| if (end <= start) return new FastBuffer(); | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| const viewByteLength = TypedArrayPrototypeGetByteLength(view); | ||||||||||||||||||||||||||||||||||||||
| const elementSize = viewByteLength / viewLength; | ||||||||||||||||||||||||||||||||||||||
| const srcByteOffset = TypedArrayPrototypeGetByteOffset(view) + | ||||||||||||||||||||||||||||||||||||||
| start * elementSize; | ||||||||||||||||||||||||||||||||||||||
| const srcByteLength = (end - start) * elementSize; | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| return fromArrayLike(new Uint8Array( | ||||||||||||||||||||||||||||||||||||||
| TypedArrayPrototypeGetBuffer(view), | ||||||||||||||||||||||||||||||||||||||
| TypedArrayPrototypeGetByteOffset(view), | ||||||||||||||||||||||||||||||||||||||
| TypedArrayPrototypeGetByteLength(view))); | ||||||||||||||||||||||||||||||||||||||
| srcByteOffset, | ||||||||||||||||||||||||||||||||||||||
| srcByteLength)); | ||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| // Identical to the built-in %TypedArray%.of(), but avoids using the deprecated | ||||||||||||||||||||||||||||||||||||||
|
|
@@ -551,14 +555,15 @@ function fromArrayBuffer(obj, byteOffset, length) { | |||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| function fromArrayLike(obj) { | ||||||||||||||||||||||||||||||||||||||
| if (obj.length <= 0) | ||||||||||||||||||||||||||||||||||||||
| const { length } = obj; | ||||||||||||||||||||||||||||||||||||||
anonrig marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||
| if (length <= 0) | ||||||||||||||||||||||||||||||||||||||
| return new FastBuffer(); | ||||||||||||||||||||||||||||||||||||||
| if (obj.length < (Buffer.poolSize >>> 1)) { | ||||||||||||||||||||||||||||||||||||||
| if (obj.length > (poolSize - poolOffset)) | ||||||||||||||||||||||||||||||||||||||
| if (length < (Buffer.poolSize >>> 1)) { | ||||||||||||||||||||||||||||||||||||||
| if (length > (poolSize - poolOffset)) | ||||||||||||||||||||||||||||||||||||||
| createPool(); | ||||||||||||||||||||||||||||||||||||||
| const b = new FastBuffer(allocPool, poolOffset, obj.length); | ||||||||||||||||||||||||||||||||||||||
| const b = new FastBuffer(allocPool, poolOffset, length); | ||||||||||||||||||||||||||||||||||||||
| TypedArrayPrototypeSet(b, obj, 0); | ||||||||||||||||||||||||||||||||||||||
| poolOffset += obj.length; | ||||||||||||||||||||||||||||||||||||||
| poolOffset += length; | ||||||||||||||||||||||||||||||||||||||
| alignPool(); | ||||||||||||||||||||||||||||||||||||||
| return b; | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
|
|
@@ -732,11 +737,7 @@ const encodingOps = { | |||||||||||||||||||||||||||||||||||||
| write: asciiWrite, | ||||||||||||||||||||||||||||||||||||||
| slice: asciiSlice, | ||||||||||||||||||||||||||||||||||||||
| indexOf: (buf, val, byteOffset, dir) => | ||||||||||||||||||||||||||||||||||||||
| indexOfBuffer(buf, | ||||||||||||||||||||||||||||||||||||||
| fromStringFast(val, encodingOps.ascii), | ||||||||||||||||||||||||||||||||||||||
| byteOffset, | ||||||||||||||||||||||||||||||||||||||
| encodingsMap.ascii, | ||||||||||||||||||||||||||||||||||||||
| dir), | ||||||||||||||||||||||||||||||||||||||
| indexOfString(buf, val, byteOffset, encodingsMap.ascii, dir), | ||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||
| base64: { | ||||||||||||||||||||||||||||||||||||||
| encoding: 'base64', | ||||||||||||||||||||||||||||||||||||||
|
|
@@ -897,17 +898,17 @@ Buffer.prototype.toString = function toString(encoding, start, end) { | |||||||||||||||||||||||||||||||||||||
| return utf8Slice(this, 0, this.length); | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| const len = this.length; | ||||||||||||||||||||||||||||||||||||||
| const bufferLength = TypedArrayPrototypeGetLength(this); | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| if (start <= 0) | ||||||||||||||||||||||||||||||||||||||
| start = 0; | ||||||||||||||||||||||||||||||||||||||
| else if (start >= len) | ||||||||||||||||||||||||||||||||||||||
| else if (start >= bufferLength) | ||||||||||||||||||||||||||||||||||||||
| return ''; | ||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||
| start = MathTrunc(start) || 0; | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| if (end === undefined || end > len) | ||||||||||||||||||||||||||||||||||||||
| end = len; | ||||||||||||||||||||||||||||||||||||||
| if (end === undefined || end > bufferLength) | ||||||||||||||||||||||||||||||||||||||
| end = bufferLength; | ||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||
| end = MathTrunc(end) || 0; | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
|
|
@@ -1118,7 +1119,9 @@ function _fill(buf, value, offset, end, encoding) { | |||||||||||||||||||||||||||||||||||||
| value = 0; | ||||||||||||||||||||||||||||||||||||||
| } else if (value.length === 1) { | ||||||||||||||||||||||||||||||||||||||
| // Fast path: If `value` fits into a single byte, use that numeric value. | ||||||||||||||||||||||||||||||||||||||
| if (normalizedEncoding === 'utf8') { | ||||||||||||||||||||||||||||||||||||||
| // ASCII shares this branch with utf8 since code < 128 covers the full | ||||||||||||||||||||||||||||||||||||||
| // ASCII range; anything outside falls through to C++ bindingFill. | ||||||||||||||||||||||||||||||||||||||
| if (normalizedEncoding === 'utf8' || normalizedEncoding === 'ascii') { | ||||||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Currently,
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, this is safe by design I am just extending the existing single byte numeric optimization to cover ASCII, since the guard already constrains it to the valid ASCII range.
thisalihassan marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||
| const code = StringPrototypeCharCodeAt(value, 0); | ||||||||||||||||||||||||||||||||||||||
| if (code < 128) { | ||||||||||||||||||||||||||||||||||||||
| value = code; | ||||||||||||||||||||||||||||||||||||||
|
|
@@ -1168,29 +1171,30 @@ function _fill(buf, value, offset, end, encoding) { | |||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| Buffer.prototype.write = function write(string, offset, length, encoding) { | ||||||||||||||||||||||||||||||||||||||
| const bufferLength = TypedArrayPrototypeGetLength(this); | ||||||||||||||||||||||||||||||||||||||
| // Buffer#write(string); | ||||||||||||||||||||||||||||||||||||||
| if (offset === undefined) { | ||||||||||||||||||||||||||||||||||||||
| return utf8Write(this, string, 0, this.length); | ||||||||||||||||||||||||||||||||||||||
| return utf8Write(this, string, 0, bufferLength); | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
| // Buffer#write(string, encoding) | ||||||||||||||||||||||||||||||||||||||
| if (length === undefined && typeof offset === 'string') { | ||||||||||||||||||||||||||||||||||||||
| encoding = offset; | ||||||||||||||||||||||||||||||||||||||
| length = this.length; | ||||||||||||||||||||||||||||||||||||||
| length = bufferLength; | ||||||||||||||||||||||||||||||||||||||
| offset = 0; | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| // Buffer#write(string, offset[, length][, encoding]) | ||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||
| validateOffset(offset, 'offset', 0, this.length); | ||||||||||||||||||||||||||||||||||||||
| validateOffset(offset, 'offset', 0, bufferLength); | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| const remaining = this.length - offset; | ||||||||||||||||||||||||||||||||||||||
| const remaining = bufferLength - offset; | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| if (length === undefined) { | ||||||||||||||||||||||||||||||||||||||
| length = remaining; | ||||||||||||||||||||||||||||||||||||||
| } else if (typeof length === 'string') { | ||||||||||||||||||||||||||||||||||||||
| encoding = length; | ||||||||||||||||||||||||||||||||||||||
| length = remaining; | ||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||
| validateOffset(length, 'length', 0, this.length); | ||||||||||||||||||||||||||||||||||||||
| validateOffset(length, 'length', 0, bufferLength); | ||||||||||||||||||||||||||||||||||||||
| if (length > remaining) | ||||||||||||||||||||||||||||||||||||||
| length = remaining; | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
|
|
@@ -1208,9 +1212,10 @@ Buffer.prototype.write = function write(string, offset, length, encoding) { | |||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| Buffer.prototype.toJSON = function toJSON() { | ||||||||||||||||||||||||||||||||||||||
| if (this.length > 0) { | ||||||||||||||||||||||||||||||||||||||
| const data = new Array(this.length); | ||||||||||||||||||||||||||||||||||||||
| for (let i = 0; i < this.length; ++i) | ||||||||||||||||||||||||||||||||||||||
| const bufferLength = TypedArrayPrototypeGetLength(this); | ||||||||||||||||||||||||||||||||||||||
| if (bufferLength > 0) { | ||||||||||||||||||||||||||||||||||||||
| const data = new Array(bufferLength); | ||||||||||||||||||||||||||||||||||||||
| for (let i = 0; i < bufferLength; ++i) | ||||||||||||||||||||||||||||||||||||||
| data[i] = this[i]; | ||||||||||||||||||||||||||||||||||||||
| return { type: 'Buffer', data }; | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
|
|
@@ -1235,7 +1240,7 @@ function adjustOffset(offset, length) { | |||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| Buffer.prototype.subarray = function subarray(start, end) { | ||||||||||||||||||||||||||||||||||||||
| const srcLength = this.length; | ||||||||||||||||||||||||||||||||||||||
| const srcLength = TypedArrayPrototypeGetLength(this); | ||||||||||||||||||||||||||||||||||||||
| start = adjustOffset(start, srcLength); | ||||||||||||||||||||||||||||||||||||||
| end = end !== undefined ? adjustOffset(end, srcLength) : srcLength; | ||||||||||||||||||||||||||||||||||||||
| const newLength = end > start ? end - start : 0; | ||||||||||||||||||||||||||||||||||||||
|
|
@@ -1253,45 +1258,52 @@ function swap(b, n, m) { | |||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| Buffer.prototype.swap16 = function swap16() { | ||||||||||||||||||||||||||||||||||||||
| // For Buffer.length < 128, it's generally faster to | ||||||||||||||||||||||||||||||||||||||
| // Ref: https://github.com/nodejs/node/pull/61871#discussion_r2889557696 | ||||||||||||||||||||||||||||||||||||||
| // For Buffer.length <= 32, it's generally faster to | ||||||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you add a reference link to this pull-request above this line |
||||||||||||||||||||||||||||||||||||||
| // do the swap in javascript. For larger buffers, | ||||||||||||||||||||||||||||||||||||||
| // dropping down to the native code is faster. | ||||||||||||||||||||||||||||||||||||||
| const len = this.length; | ||||||||||||||||||||||||||||||||||||||
| const len = TypedArrayPrototypeGetLength(this); | ||||||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While this should provide a viable defense against crashing if Welcome to Node.js v26.0.0-pre.
Type ".help" for more information.
> const { swap16 } = Buffer.prototype
undefined
> swap16(1)
Uncaught:
TypeError: Method get TypedArray.prototype.length called on incompatible receiver undefined
at get length (<anonymous>)
at swap16 (node:buffer:1265:15)
> Having this instead be a
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This would have a performance impact wouldn't it?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These are used so infrequently that I'm not concerned about the performance impact of an additional
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added swap16
I don't think any of this is now considered breaking changes, some used to work but that shouldn't have worked realistically @jasnell
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These are used so infrequently that I'm not concerned about the error being not as helpful as it could be, especially since we don't support passing an arbitrary |
||||||||||||||||||||||||||||||||||||||
| if (len % 2 !== 0) | ||||||||||||||||||||||||||||||||||||||
| throw new ERR_INVALID_BUFFER_SIZE('16-bits'); | ||||||||||||||||||||||||||||||||||||||
| if (len < 128) { | ||||||||||||||||||||||||||||||||||||||
| if (len <= 32) { | ||||||||||||||||||||||||||||||||||||||
| for (let i = 0; i < len; i += 2) | ||||||||||||||||||||||||||||||||||||||
| swap(this, i, i + 1); | ||||||||||||||||||||||||||||||||||||||
| return this; | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
| return _swap16(this); | ||||||||||||||||||||||||||||||||||||||
| _swap16(this); | ||||||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what would happen if it's called on not a TypeArrayView now?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i.e.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch, I will add a JS side guard
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. would that be good approach @ChALkeR ?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It changes the method to not being callable on a typedarray that is not an uint8array, but the previous behavior was inconsistent in that case anyway as the js part swapped elements and the src part swapped bytes So I think explicitly blocking non-uint8arr should be fine and not a semver-major?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you are right about that, I was pointing about the inconsistency about the different paths. as JS swapped the elements but alright I will work on the feedback
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not against changing the current state of things, but IMO that's a separate concern and should be discussed separately. Currently
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes that's pretty valid @aduh95, I have used
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
It does not throw but returns garbage (as in, result is not predictable / does not follow any logic) Making it swap bytes is an option. Making it throw is another option. The current behavior is length-dependent:
That is a mere oversight and not a proper api, and, more significantly, no one should be using that realistically as it doesn't work.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Passing a non-
100% agreed – and I would bet that absolutely no one is passing |
||||||||||||||||||||||||||||||||||||||
| return this; | ||||||||||||||||||||||||||||||||||||||
anonrig marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| Buffer.prototype.swap32 = function swap32() { | ||||||||||||||||||||||||||||||||||||||
| // For Buffer.length < 192, it's generally faster to | ||||||||||||||||||||||||||||||||||||||
| // Ref: https://github.com/nodejs/node/pull/61871#discussion_r2889557696 | ||||||||||||||||||||||||||||||||||||||
| // For Buffer.length <= 32, it's generally faster to | ||||||||||||||||||||||||||||||||||||||
| // do the swap in javascript. For larger buffers, | ||||||||||||||||||||||||||||||||||||||
| // dropping down to the native code is faster. | ||||||||||||||||||||||||||||||||||||||
| const len = this.length; | ||||||||||||||||||||||||||||||||||||||
| const len = TypedArrayPrototypeGetLength(this); | ||||||||||||||||||||||||||||||||||||||
| if (len % 4 !== 0) | ||||||||||||||||||||||||||||||||||||||
| throw new ERR_INVALID_BUFFER_SIZE('32-bits'); | ||||||||||||||||||||||||||||||||||||||
| if (len < 192) { | ||||||||||||||||||||||||||||||||||||||
| if (len <= 32) { | ||||||||||||||||||||||||||||||||||||||
| for (let i = 0; i < len; i += 4) { | ||||||||||||||||||||||||||||||||||||||
| swap(this, i, i + 3); | ||||||||||||||||||||||||||||||||||||||
| swap(this, i + 1, i + 2); | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
| return this; | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
| return _swap32(this); | ||||||||||||||||||||||||||||||||||||||
| _swap32(this); | ||||||||||||||||||||||||||||||||||||||
| return this; | ||||||||||||||||||||||||||||||||||||||
anonrig marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| Buffer.prototype.swap64 = function swap64() { | ||||||||||||||||||||||||||||||||||||||
| // For Buffer.length < 192, it's generally faster to | ||||||||||||||||||||||||||||||||||||||
| // Ref: https://github.com/nodejs/node/pull/61871#discussion_r2889557696 | ||||||||||||||||||||||||||||||||||||||
| // For Buffer.length < 48, it's generally faster to | ||||||||||||||||||||||||||||||||||||||
| // do the swap in javascript. For larger buffers, | ||||||||||||||||||||||||||||||||||||||
| // dropping down to the native code is faster. | ||||||||||||||||||||||||||||||||||||||
| const len = this.length; | ||||||||||||||||||||||||||||||||||||||
| // Threshold differs from swap16/swap32 (<=32) because swap64's | ||||||||||||||||||||||||||||||||||||||
| // crossover is between 40 and 48 (native wins at 48, loses at 40). | ||||||||||||||||||||||||||||||||||||||
| const len = TypedArrayPrototypeGetLength(this); | ||||||||||||||||||||||||||||||||||||||
| if (len % 8 !== 0) | ||||||||||||||||||||||||||||||||||||||
| throw new ERR_INVALID_BUFFER_SIZE('64-bits'); | ||||||||||||||||||||||||||||||||||||||
| if (len < 192) { | ||||||||||||||||||||||||||||||||||||||
| if (len < 48) { | ||||||||||||||||||||||||||||||||||||||
thisalihassan marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||
| for (let i = 0; i < len; i += 8) { | ||||||||||||||||||||||||||||||||||||||
| swap(this, i, i + 7); | ||||||||||||||||||||||||||||||||||||||
| swap(this, i + 1, i + 6); | ||||||||||||||||||||||||||||||||||||||
|
|
@@ -1300,7 +1312,8 @@ Buffer.prototype.swap64 = function swap64() { | |||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
| return this; | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
| return _swap64(this); | ||||||||||||||||||||||||||||||||||||||
| _swap64(this); | ||||||||||||||||||||||||||||||||||||||
| return this; | ||||||||||||||||||||||||||||||||||||||
anonrig marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| Buffer.prototype.toLocaleString = Buffer.prototype.toString; | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.