<!--your preparation HTML code goes here-->
function generateRandomBitmasks(count = 100) {
const bitmasks = new Array(count);
for (let i = 0; i < count; i++) {
let bitLength = Math.floor(Math.random() * (32 - 5 + 1)) + 5;
bitmasks[i] = Math.floor(Math.random() * (1 << bitLength));
}
return bitmasks;
}
var bitmasks = generateRandomBitmasks();
var packed = packBitmasks(bitmasks);
var packedV8 = packBitmasksV8(bitmasks);
function packBitmasks(bitmasks) {
let totalBits = bitmasks.length * 32;
let packedSize = Math.ceil(totalBits / 8);
let packed = new Uint8Array(packedSize);
let bitIndex = 0;
for (let i = 0; i < bitmasks.length; i++) {
let value = bitmasks[i];
for (let b = 0; b < 32; b++) {
if (bitIndex >= totalBits) break;
let bytePos = bitIndex >> 3;
let bitPos = bitIndex % 8;
if (value & (1 << b)) {
packed[bytePos] |= (1 << bitPos);
}
bitIndex++;
}
}
return packed;
}
function unpackBitmasks(packed, length) {
let bitmasks = new Uint32Array(length);
let bitIndex = 0;
for (let i = 0; i < length; i++) {
let value = 0;
for (let b = 0; b < 32; b++) {
if (bitIndex >= packed.length * 8) break;
let bytePos = bitIndex >> 3;
let bitPos = bitIndex % 8;
if (packed[bytePos] & (1 << bitPos)) {
value |= (1 << b);
}
bitIndex++;
}
bitmasks[i] = value;
}
return bitmasks;
}
function packBitmasksV8(bitmasks) {
let packed = new Uint8Array(bitmasks.length * 4);
let packedView = new Uint32Array(packed.buffer);
for (let i = 0, len = bitmasks.length; i < len; i++) {
packedView[i] = bitmasks[i];
}
return packed;
}
function unpackBitmasksV8(packed) {
let packedView = new Uint32Array(packed.buffer);
let bitmasks = new Array(packedView.length);
for (let i = 0, len = packedView.length; i < len; i++) {
bitmasks[i] = packedView[i];
}
return bitmasks;
}
packBitmasks(bitmasks)
unpackBitmasks(packed)
packBitmasksV8(bitmasks)
unpackBitmasksV8(packedV8)
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
Pack | |
UnPack | |
Pack (Optimized) | |
UnPack (Optimized) |
Test name | Executions per second |
---|---|
Pack | 383031.8 Ops/sec |
UnPack | 53071896.0 Ops/sec |
Pack (Optimized) | 2796965.0 Ops/sec |
UnPack (Optimized) | 13323087.0 Ops/sec |
The provided benchmark tests the performance of two different methods for packing and unpacking arrays of bitmasks in JavaScript. Specifically, it compares a standard packing approach with an optimized version designed to leverage JavaScript's typed arrays more effectively. Below is a detailed explanation of what is being compared and the implications of those comparisons:
packBitmasks(bitmasks)
:
Uint8Array
. This is done by iterating over each bitmask and setting the corresponding bits in the byte array.packBitmasksV8(bitmasks)
:
Uint32Array
to perform the packing more directly, which is generally faster as it avoids bit manipulation at a per-bit level.unpackBitmasks(packed)
:
Uint8Array
back into the original bitmask array. It processes each bit by examining the packed byte array.unpackBitmasksV8(packed)
:
Uint32Array
.The results of the benchmark provide insight into the performance of each method:
UnPack
: 53,071,896 executions per second, indicating superior performance in unpacking the standard bitmasks.UnPack (Optimized)
: 13,323,087 executions per second, significantly slower than the normal unpacking method but still faster than the packing methods.Pack (Optimized)
: 2,796,965 executions per second, reflecting improved performance over the standard packing method.Pack
: 383,031.84 executions per second, demonstrating the slowest performance due to the detailed bit manipulation process.Uint32Array
and Uint8Array
) should offer better memory usage patterns due to careful packing and alignment.Using Libraries:
bitset.js
or Uint8Array
based libraries that provide higher-level APIs for managing bitmasks and might save development and maintenance time.Native Data Structures:
Alternative Packing Algorithms:
In summary, the benchmark illustrates the performance differences between two packing and unpacking strategies, effectively demonstrating how JavaScript can utilize low-level data types like Uint8Array
and Uint32Array
for efficiency. Each method has its strengths and weaknesses, contributing to deeper considerations in performance-oriented applications.