<!--your preparation HTML code goes here-->
function bigIntToBigEndianBytesLoopParseInt(value) {
const hex = value.toString(16).padStart(16, '0');
const bytes = new Uint8Array(8);
for (let i = 0; i < 8; i++) {
bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
}
return bytes;
}
function bigIntToBigEndianBytesLoopConstructor(value) {
const hex = value.toString(16).padStart(16, '0');
const bytes = new Uint8Array(8);
for (let i = 0; i < 8; i++) {
bytes[i] = Number(hex.slice(i * 2, i * 2 + 2), 16);
}
return bytes;
}
function bigIntToBigEndianBytesDataView(value) {
const buf = new ArrayBuffer(8);
const view = new DataView(buf);
view.setBigUint64(0, value);
return new Uint8Array(buf);
}
function bigIntToUint8ArrayDirectConstructor(value) {
const result = new Uint8Array(8);
result[7] = Number(value & 0xffn);
result[6] = Number((value >> 8n) & 0xffn);
result[5] = Number((value >> 16n) & 0xffn);
result[4] = Number((value >> 24n) & 0xffn );
result[3] = Number((value >> 32n) & 0xffn);
result[2] = Number((value >> 40n) & 0xffn);
result[1] = Number((value >> 48n) & 0xffn);
result[0] = Number((value >> 56n) & 0xffn);
return result;
}
// Added by trincot: first split BigInt into two numbers (32 bit), then work with those only
function bigIntToUint8ArrayDirectConstructor2(value) {
const result = new Uint8Array(8);
const low = Number(value & 0xffffffffn);
const high = Number((value >> 32n) & 0xffffffffn);
result[7] = low & 0xff;
result[6] = (low >> 8) & 0xff;
result[5] = (low >> 16) & 0xff;
result[4] = (low >> 24) & 0xff;
result[3] = high & 0xff;
result[2] = (high >> 8) & 0xff;
result[1] = (high >> 16) & 0xff;
result[0] = (high >> 24) & 0xff;
return result;
}
function bigIntToUint8ArrayDirectParseInt(value) {
const result = new Uint8Array(8);
result[7] = parseInt(value & 0xffn);
result[6] = parseInt((value >> 8n) & 0xffn);
result[5] = parseInt((value >> 16n) & 0xffn);
result[4] = parseInt((value >> 24n) & 0xffn );
result[3] = parseInt((value >> 32n) & 0xffn);
result[2] = parseInt((value >> 40n) & 0xffn);
result[1] = parseInt((value >> 48n) & 0xffn);
result[0] = parseInt((value >> 56n) & 0xffn);
return result;
}
bigIntToBigEndianBytesLoopParseInt(32149814014n)
bigIntToBigEndianBytesLoopConstructor(32149814014n)
bigIntToBigEndianBytesDataView(32149814014n)
bigIntToUint8ArrayDirectConstructor(32149814014n)
bigIntToUint8ArrayDirectParseInt(32149814014n)
bigIntToUint8ArrayDirectConstructor2(32149814014n)
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
Loop ParseInt | |
Loop Constructor | |
DataView | |
Direct Constructor | |
Direct ParseInt | |
Direct Constructor with split |
Test name | Executions per second |
---|---|
Loop ParseInt | 1699444.9 Ops/sec |
Loop Constructor | 1687497.1 Ops/sec |
DataView | 1749622.6 Ops/sec |
Direct Constructor | 5739882.5 Ops/sec |
Direct ParseInt | 1591703.2 Ops/sec |
Direct Constructor with split | 9620428.0 Ops/sec |
The benchmark described in the provided JSON is designed to evaluate various methods for converting a BigInt to a Big-endian byte array in JavaScript. Each test case focuses on a distinct implementation strategy for the conversion, allowing for a comparison of performance in terms of the number of executions per second.
Loop with parseInt
:
bigIntToBigEndianBytesLoopParseInt(value)
parseInt
.parseInt
can introduce overhead due to its string parsing.Loop with Constructor:
bigIntToBigEndianBytesLoopConstructor(value)
Number
constructor to convert hex slices directly to bytes.parseInt
.DataView:
bigIntToBigEndianBytesDataView(value)
DataView
to directly set bytes in an ArrayBuffer
.Direct Constructor:
bigIntToUint8ArrayDirectConstructor(value)
Direct ParseInt:
bigIntToUint8ArrayDirectParseInt(value)
parseInt
for each byte after shifting.parseInt
.Direct Constructor with Split:
bigIntToUint8ArrayDirectConstructor2(value)
From the benchmark results:
While these implementations can be influenced by specific JavaScript engines and environments, generally:
For developers looking at alternatives, methods in other languages (like using Buffer
in Node.js, or methods in Python leveraging libraries like NumPy) could provide additional context or performance characteristics. However, in JavaScript, these implementations showcase the flexibility of handling BigInts and the impact of chosen methodologies on performance.
Software engineers should choose the approach that meets their specific needs while considering maintainability, readability, and performance based on the context of their application.