buffer: add {read|write}Big[U]Int64{BE|LE} methods #19691
Conversation
lib/internal/buffer.js
Outdated
| if (first === undefined || last === undefined) | ||
| boundsError(offset, this.length - 8); | ||
|
|
||
| // TODO: do we need tricky math from readUInt48LE? |
You mean the (a + b * 256) * 2 ** 32 bit?
I expect it's faster to compute the high and low words as 32 bits quantities first, then convert them to bigints:
const lo = /* ... */;
const hi = /* ... */;
return BigInt(lo) + BigInt(hi) * 2n ** 32n;I'm unsure if V8 currently constant-folds the 2n ** 32n so you might want to cache that.
It's probably faster now, but I would prefer to put off any optimizations until V8 6.7 is out.
Have you considered using A << Bn instead of A * 2n ** Bn (everywhere)?
It's shorter and IMO easier to read.
it's also much more easily optimized :D
I chose to use the same approach as in other read functions.
Caching is indeed faster:
confidence improvement accuracy (*) (**) (***)
buffers\\buffer-read.js n=1000000 type='BigInt64BE' buffer='fast' *** 36.14 % ±4.71% ±6.26% ±8.15%
buffers\\buffer-read.js n=1000000 type='BigInt64BE' buffer='slow' *** 32.26 % ±5.68% ±7.58% ±9.92%
buffers\\buffer-read.js n=1000000 type='BigInt64LE' buffer='fast' *** 37.72 % ±4.18% ±5.58% ±7.29%
buffers\\buffer-read.js n=1000000 type='BigInt64LE' buffer='slow' *** 34.75 % ±5.00% ±6.66% ±8.67%
buffers\\buffer-read.js n=1000000 type='BigUInt64BE' buffer='fast' *** 34.65 % ±3.41% ±4.56% ±5.97%
buffers\\buffer-read.js n=1000000 type='BigUInt64BE' buffer='slow' *** 35.73 % ±3.70% ±4.92% ±6.42%
buffers\\buffer-read.js n=1000000 type='BigUInt64LE' buffer='fast' *** 30.61 % ±3.91% ±5.20% ±6.78%
buffers\\buffer-read.js n=1000000 type='BigUInt64LE' buffer='slow' *** 32.13 % ±3.36% ±4.47% ±5.83%
But using bitwise shift instead of multiplication as @targos suggested is equally fast, and less ugly than a constant, so I went with that.
| --> | ||
|
|
||
| * `offset` {integer} Number of bytes to skip before starting to read. Must satisfy: `0 <= offset <= buf.length - 8`. | ||
| * Returns: {bigint} |
It seems MDN have not a BigInt doc yet, but maybe we can add a link to spec or proposal in customTypesMap for now?
Let's put it off for now. Maybe it will be on MDN when it's time to land.
Still not on MDN. What do others think about adding a link to the proposal?
I would link to the proposal
We already have a precedent:
Line 32 in cd8f06f
Good find.
Addressed in #27101
|
Have you considered using something that already exists in the language, namely |
|
@TimothyGu I doubt that this is going to be as fast as doing this in JS but we could of course try. |
|
Comments addressed, PTAL. @TimothyGu last time this was attempted (in the PR you linked) the results were disappointing, so I don't think it would be worthwhile to pursue this again. |
|
Added a link to the spec. Hope it works, because I can't build docs on Windows. |
tools/doc/type-parser.js
Outdated
| @@ -4,6 +4,7 @@ const jsDocPrefix = 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/'; | |||
|
|
|||
| const jsDataStructuresUrl = `${jsDocPrefix}Data_structures`; | |||
| const jsPrimitives = { | |||
| bigint: 'BigInt', | |||
Unfortunately, we cannot add this here, otherwise, the link would be wrong from this code path:
Lines 140 to 143 in cd8f06f
So let us just leave the second one for now.
It is possible, though tricky. Building just one doc is simpler, but it will not be styled properly if not placed with assets (which is not needed for simple build test: node.exe tools/doc/generate.js --format=html --node-version=11.0.0 --analytics= doc/api/buffer.md > buffer.html |
| for (var i = 0n; i !== n; i++) { | ||
| buff[fn](i & m, 0); | ||
| } | ||
| bench.end(Number(n)); |
It's minor, but I had trouble choosing between the following options:
nandiare Numbers, convertito BigInt in the call (BigInt(i) & m).nis Number,iis BigInt, use!=in the loop.nandiare BigInts, convert to Number beforebench.end()call.
It's now using option 3, but I'm not sure it's the best.
Seems fine to me. You could do const nn = Number(n) before bench.start() if you're worried about the coercion influencing the benchmark numbers.
It's already converted to BigInt in main().
I mean the coercion in bench.end(Number(n)).
|
@nodejs/buffer PTAL I'm not sure how to fix the |
|
@seishun add |
|
The remaining issue is lines 594 and 598. How do we usually deal with long function calls? |
|
@seishun It seems something like this will do: return writeBigU_Int64LE(
this, value, offset, -0x8000000000000000n, 0x7fffffffffffffffn); |
|
@vsemozhetbyt thanks, seems good. New CI: https://ci.nodejs.org/job/node-test-pull-request/15366/ |
|
Rebased on master now that #21237 has landed. New CI: https://ci.nodejs.org/job/node-test-pull-request/15388/ |
LGTM with comments/suggestions.
| for (var i = 0n; i !== n; i++) { | ||
| buff[fn](i & m, 0); | ||
| } | ||
| bench.end(Number(n)); |
Seems fine to me. You could do const nn = Number(n) before bench.start() if you're worried about the coercion influencing the benchmark numbers.
Some doc nits. Otherwise LGTM.
PR-URL: nodejs/node#19691 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
|
I've added the |
Backport-PR-URL: nodejs#30361 PR-URL: nodejs#19691 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> (cherry picked from commit 3d8532f)
Backport-PR-URL: #30361 PR-URL: #19691 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Notable changes:
- buffer: add {read|write}Big\[U\]Int64{BE|LE} methods (garygsc)
[#19691](#19691)
- deps:
- upgrade to libuv 1.34.2 (cjihrig)
[#31477](#31477)
- upgrade npm to 6.13.7 (Michael Perrotte)
[#31558](#31558)
- n-api:
- add napi\_get\_all\_property\_names (himself65)
[#30006](#30006)
- add APIs for per-instance state management (Gabriel Schulhof)
[#28682](#28682)
- turn NAPI\_CALL\_INTO\_MODULE into a function (Anna Henningsen)
[#26128](#26128)
- tls: support TLS min/max protocol defaults in CLI (Sam Roberts)
[#27946](#27946)
PR-URL: #31984
Notable changes:
- buffer: add {read|write}Big\[U\]Int64{BE|LE} methods (garygsc)
[#19691](#19691)
- deps:
- upgrade to libuv 1.34.2 (cjihrig)
[#31477](#31477)
- upgrade npm to 6.13.7 (Michael Perrotte)
[#31558](#31558)
- n-api:
- add napi\_get\_all\_property\_names (himself65)
[#30006](#30006)
- add APIs for per-instance state management (Gabriel Schulhof)
[#28682](#28682)
- turn NAPI\_CALL\_INTO\_MODULE into a function (Anna Henningsen)
[#26128](#26128)
- tls:
- expose keylog event on TLSSocket (Alba Mendez)
[#27654](#27654)
- support TLS min/max protocol defaults in CLI (Sam Roberts)
[#27946](#27946)
PR-URL: #31984
Notable changes:
- buffer: add {read|write}Big\[U\]Int64{BE|LE} methods (garygsc)
[#19691](#19691)
- deps:
- update npm to 6.14.3 (Myles Borins)
[#32368](#32368)
- upgrade to libuv 1.34.2 (cjihrig)
[#31477](#31477)
- n-api:
- add napi\_get\_all\_property\_names (himself65)
[#30006](#30006)
- add APIs for per-instance state management (Gabriel Schulhof)
[#28682](#28682)
- turn NAPI\_CALL\_INTO\_MODULE into a function (Anna Henningsen)
[#26128](#26128)
- tls:
- expose keylog event on TLSSocket (Alba Mendez)
[#27654](#27654)
- support TLS min/max protocol defaults in CLI (Sam Roberts)
[#27946](#27946)
PR-URL: #31984
Notable changes:
- buffer: add {read|write}Big\[U\]Int64{BE|LE} methods (garygsc)
[#19691](#19691)
- deps:
- update npm to 6.14.3 (Myles Borins)
[#32368](#32368)
- upgrade to libuv 1.34.2 (cjihrig)
[#31477](#31477)
- n-api:
- add napi\_get\_all\_property\_names (himself65)
[#30006](#30006)
- add APIs for per-instance state management (Gabriel Schulhof)
[#28682](#28682)
- turn NAPI\_CALL\_INTO\_MODULE into a function (Anna Henningsen)
[#26128](#26128)
- tls:
- expose keylog event on TLSSocket (Alba Mendez)
[#27654](#27654)
- support TLS min/max protocol defaults in CLI (Sam Roberts)
[#27946](#27946)
PR-URL: #31984
Notable changes:
- buffer: add {read|write}Big\[U\]Int64{BE|LE} methods (garygsc)
[#19691](#19691)
- deps:
- update npm to 6.14.3 (Myles Borins)
[#32368](#32368)
- upgrade openssl sources to 1.1.1e (Hassaan Pasha)
[#32328](#32328)
- upgrade to libuv 1.34.2 (cjihrig)
[#31477](#31477)
- n-api:
- add napi\_get\_all\_property\_names (himself65)
[#30006](#30006)
- add APIs for per-instance state management (Gabriel Schulhof)
[#28682](#28682)
- turn NAPI\_CALL\_INTO\_MODULE into a function (Anna Henningsen)
[#26128](#26128)
- tls:
- expose keylog event on TLSSocket (Alba Mendez)
[#27654](#27654)
- support TLS min/max protocol defaults in CLI (Sam Roberts)
[#27946](#27946)
- url: handle quasi-WHATWG URLs in urlToOptions() (cjihrig)
[#26226](#26226)
PR-URL: #31984
Notable changes:
- buffer: add {read|write}Big\[U\]Int64{BE|LE} methods (garygsc)
[#19691](#19691)
- deps:
- update npm to 6.14.3 (Myles Borins)
[#32368](#32368)
- upgrade openssl sources to 1.1.1e (Hassaan Pasha)
[#32328](#32328)
- upgrade to libuv 1.34.2 (cjihrig)
[#31477](#31477)
- n-api:
- add napi\_get\_all\_property\_names (himself65)
[#30006](#30006)
- add APIs for per-instance state management (Gabriel Schulhof)
[#28682](#28682)
- turn NAPI\_CALL\_INTO\_MODULE into a function (Anna Henningsen)
[#26128](#26128)
- tls:
- expose keylog event on TLSSocket (Alba Mendez)
[#27654](#27654)
- support TLS min/max protocol defaults in CLI (Sam Roberts)
[#27946](#27946)
- url: handle quasi-WHATWG URLs in urlToOptions() (cjihrig)
[#26226](#26226)
PR-URL: #31984
Notable changes:
- buffer: add {read|write}Big\[U\]Int64{BE|LE} methods (garygsc)
[#19691](#19691)
- deps:
- update npm to 6.14.3 (Myles Borins)
[#32368](#32368)
- upgrade openssl sources to 1.1.1e (Hassaan Pasha)
[#32328](#32328)
- upgrade to libuv 1.34.2 (cjihrig)
[#31477](#31477)
- n-api:
- add napi\_get\_all\_property\_names (himself65)
[#30006](#30006)
- add APIs for per-instance state management (Gabriel Schulhof)
[#28682](#28682)
- turn NAPI\_CALL\_INTO\_MODULE into a function (Anna Henningsen)
[#26128](#26128)
- tls:
- expose keylog event on TLSSocket (Alba Mendez)
[#27654](#27654)
- support TLS min/max protocol defaults in CLI (Sam Roberts)
[#27946](#27946)
- url: handle quasi-WHATWG URLs in urlToOptions() (cjihrig)
[#26226](#26226)
PR-URL: #31984
Notable changes:
- buffer: add {read|write}Big\[U\]Int64{BE|LE} methods (garygsc)
[#19691](#19691)
- build: macOS package notarization (Rod Vagg)
[#31459](#31459)
- deps:
- update npm to 6.14.3 (Myles Borins)
[#32368](#32368)
- upgrade openssl sources to 1.1.1e (Hassaan Pasha)
[#32328](#32328)
- upgrade to libuv 1.34.2 (cjihrig)
[#31477](#31477)
- n-api:
- add napi\_get\_all\_property\_names (himself65)
[#30006](#30006)
- add APIs for per-instance state management (Gabriel Schulhof)
[#28682](#28682)
- turn NAPI\_CALL\_INTO\_MODULE into a function (Anna Henningsen)
[#26128](#26128)
- tls:
- expose keylog event on TLSSocket (Alba Mendez)
[#27654](#27654)
- support TLS min/max protocol defaults in CLI (Sam Roberts)
[#27946](#27946)
- url: handle quasi-WHATWG URLs in urlToOptions() (cjihrig)
[#26226](#26226)
PR-URL: #31984
Notable changes:
- buffer: add {read|write}Big\[U\]Int64{BE|LE} methods (garygsc)
[#19691](#19691)
- build: macOS package notarization (Rod Vagg)
[#31459](#31459)
- deps:
- update npm to 6.14.3 (Myles Borins)
[#32368](#32368)
- upgrade openssl sources to 1.1.1e (Hassaan Pasha)
[#32328](#32328)
- upgrade to libuv 1.34.2 (cjihrig)
[#31477](#31477)
- n-api:
- add napi\_get\_all\_property\_names (himself65)
[#30006](#30006)
- add APIs for per-instance state management (Gabriel Schulhof)
[#28682](#28682)
- define release 6
[#32058](#32058)
- turn NAPI\_CALL\_INTO\_MODULE into a function (Anna Henningsen)
[#26128](#26128)
- tls:
- expose keylog event on TLSSocket (Alba Mendez)
[#27654](#27654)
- support TLS min/max protocol defaults in CLI (Sam Roberts)
[#27946](#27946)
- url: handle quasi-WHATWG URLs in urlToOptions() (cjihrig)
[#26226](#26226)
PR-URL: #31984
macOS package notarization and a change in builder configuration
The macOS binaries for this release, and future 10.x releases, are now
being compiled on macOS 10.15 (Catalina) with Xcode 11 to support
package notarization, a requirement for installing .pkg files on macOS
10.15 and later. Previous builds of Node.js 10.x were compiled on macOS
10.7 (Lion). As binaries are still being compiled to support a minimum
of macOS 10.7 (Lion) we do not anticipate this having a negative impact
on Node.js 10.x users with older versions of macOS.
Notable changes:
- buffer: add {read|write}Big\[U\]Int64{BE|LE} methods (garygsc)
[#19691](#19691)
- build: macOS package notarization (Rod Vagg)
[#31459](#31459)
- deps:
- update npm to 6.14.3 (Myles Borins)
[#32368](#32368)
- upgrade openssl sources to 1.1.1e (Hassaan Pasha)
[#32328](#32328)
- upgrade to libuv 1.34.2 (cjihrig)
[#31477](#31477)
- n-api:
- add napi\_get\_all\_property\_names (himself65)
[#30006](#30006)
- add APIs for per-instance state management (Gabriel Schulhof)
[#28682](#28682)
- define release 6
[#32058](#32058)
- turn NAPI\_CALL\_INTO\_MODULE into a function (Anna Henningsen)
[#26128](#26128)
- tls:
- expose keylog event on TLSSocket (Alba Mendez)
[#27654](#27654)
- support TLS min/max protocol defaults in CLI (Sam Roberts)
[#27946](#27946)
- url: handle quasi-WHATWG URLs in urlToOptions() (cjihrig)
[#26226](#26226)
PR-URL: #31984
macOS package notarization and a change in builder configuration
The macOS binaries for this release, and future 10.x releases, are now
being compiled on macOS 10.15 (Catalina) with Xcode 11 to support
package notarization, a requirement for installing .pkg files on macOS
10.15 and later. Previous builds of Node.js 10.x were compiled on macOS
10.10 (Yosemite) with a minimum deployment target of macOS 10.7 (Lion).
As binaries are still being compiled to support a minimum of macOS 10.7
(Lion) we do not anticipate this having a negative impact on Node.js
10.x users with older versions of macOS.
Notable changes:
- buffer: add {read|write}Big\[U\]Int64{BE|LE} methods (garygsc)
[#19691](#19691)
- build: macOS package notarization (Rod Vagg)
[#31459](#31459)
- deps:
- update npm to 6.14.3 (Myles Borins)
[#32368](#32368)
- upgrade openssl sources to 1.1.1e (Hassaan Pasha)
[#32328](#32328)
- upgrade to libuv 1.34.2 (cjihrig)
[#31477](#31477)
- n-api:
- add napi\_get\_all\_property\_names (himself65)
[#30006](#30006)
- add APIs for per-instance state management (Gabriel Schulhof)
[#28682](#28682)
- define release 6
[#32058](#32058)
- turn NAPI\_CALL\_INTO\_MODULE into a function (Anna Henningsen)
[#26128](#26128)
- tls:
- expose keylog event on TLSSocket (Alba Mendez)
[#27654](#27654)
- support TLS min/max protocol defaults in CLI (Sam Roberts)
[#27946](#27946)
- url: handle quasi-WHATWG URLs in urlToOptions() (cjihrig)
[#26226](#26226)
PR-URL: #31984
macOS package notarization and a change in builder configuration
The macOS binaries for this release, and future 10.x releases, are now
being compiled on macOS 10.15 (Catalina) with Xcode 11 to support
package notarization, a requirement for installing .pkg files on macOS
10.15 and later. Previous builds of Node.js 10.x were compiled on macOS
10.10 (Yosemite) with a minimum deployment target of macOS 10.7 (Lion).
As binaries are still being compiled to support a minimum of macOS 10.7
(Lion) we do not anticipate this having a negative impact on Node.js
10.x users with older versions of macOS.
Notable changes:
- buffer: add {read|write}Big\[U\]Int64{BE|LE} methods (garygsc)
[#19691](#19691)
- build: macOS package notarization (Rod Vagg)
[#31459](#31459)
- deps:
- update npm to 6.14.3 (Myles Borins)
[#32368](#32368)
- upgrade openssl sources to 1.1.1e (Hassaan Pasha)
[#32328](#32328)
- upgrade to libuv 1.34.2 (cjihrig)
[#31477](#31477)
- n-api:
- add napi\_get\_all\_property\_names (himself65)
[#30006](#30006)
- add APIs for per-instance state management (Gabriel Schulhof)
[#28682](#28682)
- define release 6
[#32058](#32058)
- turn NAPI\_CALL\_INTO\_MODULE into a function (Anna Henningsen)
[#26128](#26128)
- tls:
- expose keylog event on TLSSocket (Alba Mendez)
[#27654](#27654)
- support TLS min/max protocol defaults in CLI (Sam Roberts)
[#27946](#27946)
- url: handle quasi-WHATWG URLs in urlToOptions() (cjihrig)
[#26226](#26226)
PR-URL: #31984
macOS package notarization and a change in builder configuration
The macOS binaries for this release, and future 10.x releases, are now
being compiled on macOS 10.15 (Catalina) with Xcode 11 to support
package notarization, a requirement for installing .pkg files on macOS
10.15 and later. Previous builds of Node.js 10.x were compiled on macOS
10.10 (Yosemite) with a minimum deployment target of macOS 10.7 (Lion).
As binaries are still being compiled to support a minimum of macOS 10.7
(Lion) we do not anticipate this having a negative impact on Node.js
10.x users with older versions of macOS.
Notable changes:
- buffer: add {read|write}Big\[U\]Int64{BE|LE} methods (garygsc)
[#19691](#19691)
- build: macOS package notarization (Rod Vagg)
[#31459](#31459)
- deps:
- update npm to 6.14.3 (Myles Borins)
[#32368](#32368)
- upgrade openssl sources to 1.1.1e (Hassaan Pasha)
[#32328](#32328)
- upgrade to libuv 1.34.2 (cjihrig)
[#31477](#31477)
- n-api:
- add napi\_get\_all\_property\_names (himself65)
[#30006](#30006)
- add APIs for per-instance state management (Gabriel Schulhof)
[#28682](#28682)
- define release 6
[#32058](#32058)
- turn NAPI\_CALL\_INTO\_MODULE into a function (Anna Henningsen)
[#26128](#26128)
- tls:
- expose keylog event on TLSSocket (Alba Mendez)
[#27654](#27654)
- support TLS min/max protocol defaults in CLI (Sam Roberts)
[#27946](#27946)
- url: handle quasi-WHATWG URLs in urlToOptions() (cjihrig)
[#26226](#26226)
PR-URL: #31984
macOS package notarization and a change in builder configuration
The macOS binaries for this release, and future 10.x releases, are now
being compiled on macOS 10.15 (Catalina) with Xcode 11 to support
package notarization, a requirement for installing .pkg files on macOS
10.15 and later. Previous builds of Node.js 10.x were compiled on macOS
10.10 (Yosemite) with a minimum deployment target of macOS 10.7 (Lion).
As binaries are still being compiled to support a minimum of macOS 10.7
(Lion) we do not anticipate this having a negative impact on Node.js
10.x users with older versions of macOS.
Notable changes:
- buffer: add {read|write}Big\[U\]Int64{BE|LE} methods (garygsc)
[#19691](#19691)
- build: macOS package notarization (Rod Vagg)
[#31459](#31459)
- deps:
- update npm to 6.14.3 (Myles Borins)
[#32368](#32368)
- upgrade openssl sources to 1.1.1e (Hassaan Pasha)
[#32328](#32328)
- upgrade to libuv 1.34.2 (cjihrig)
[#31477](#31477)
- n-api:
- add napi\_get\_all\_property\_names (himself65)
[#30006](#30006)
- add APIs for per-instance state management (Gabriel Schulhof)
[#28682](#28682)
- define release 6
[#32058](#32058)
- turn NAPI\_CALL\_INTO\_MODULE into a function (Anna Henningsen)
[#26128](#26128)
- tls:
- expose keylog event on TLSSocket (Alba Mendez)
[#27654](#27654)
- support TLS min/max protocol defaults in CLI (Sam Roberts)
[#27946](#27946)
- url: handle quasi-WHATWG URLs in urlToOptions() (cjihrig)
[#26226](#26226)
PR-URL: #31984
This is a resurrection of #15152, this time with BigInts.
The functions👍 it or whatever if you agree.
writeBigU_Int64LEandwriteBigU_Int64BElook so terrible because settingUint8Arrayvalues toBigIntis disallowed by the spec. I submitted an issue about it in tc39/proposal-bigint#137. PleaseChecklist
make -j4 test(UNIX), orvcbuild test(Windows) passesThe text was updated successfully, but these errors were encountered: