var bytes = Array.from({length: 1000}, e => 0xff * Math.random() | 0);
var uint16 = new Uint16Array(bytes);
var uint8 = new Uint8Array(bytes);
function base64ArrayBuffer(arrayBuffer) {
var base64 = '';
var encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
var bytes = arrayBuffer;
var byteLength = bytes.byteLength;
var byteRemainder = byteLength % 3;
var mainLength = byteLength - byteRemainder;
var a, b, c, d;
var chunk;
// Main loop deals with bytes in chunks of 3
for (var i = 0; i < mainLength; i = i + 3) {
// Combine the three bytes into a single integer
chunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];
// Use bitmasks to extract 6-bit segments from the triplet
a = (chunk & 16515072) >> 18; // 16515072 = (2^6 - 1) << 18
b = (chunk & 258048) >> 12; // 258048 = (2^6 - 1) << 12
c = (chunk & 4032) >> 6; // 4032 = (2^6 - 1) << 6
d = chunk & 63; // 63 = 2^6 - 1
// Convert the raw binary segments to the appropriate ASCII encoding
base64 += encodings[a] + encodings[b] + encodings[c] + encodings[d];
}
// Deal with the remaining bytes and padding
if (byteRemainder == 1) {
chunk = bytes[mainLength];
a = (chunk & 252) >> 2; // 252 = (2^6 - 1) << 2
// Set the 4 least significant bits to zero
b = (chunk & 3) << 4; // 3 = 2^2 - 1
base64 += encodings[a] + encodings[b] + '==';
} else if (byteRemainder == 2) {
chunk = (bytes[mainLength] << 8) | bytes[mainLength + 1];
a = (chunk & 64512) >> 10; // 64512 = (2^6 - 1) << 10
b = (chunk & 1008) >> 4; // 1008 = (2^6 - 1) << 4
// Set the 2 least significant bits to zero;
c = (chunk & 15) << 2 // 15 = 2^4 - 1
base64 += encodings[a] + encodings[b] + encodings[c] + '=';
}
return base64;
}
globalThis.btoa(String.fromCharCode.apply(null, uint16));
base64ArrayBuffer(uint8);
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
String.fromCharCode & btoa | |
base64ArrayBuffer function |
Test name | Executions per second |
---|---|
String.fromCharCode & btoa | 101340.0 Ops/sec |
base64ArrayBuffer function | 64331.1 Ops/sec |
Let's break down the provided benchmark and its options.
Benchmark Definition
The test cases use two different approaches to encode a large array of bytes into Base64 format:
globalThis.btoa(String.fromCharCode.apply(null, uint16))
: This approach uses the built-in btoa
function, which is a part of the Web API. String.fromCharCode
is used to create an array of Unicode code points from the input byte array.base64ArrayBuffer(uint8)
: This approach is implemented in JavaScript code and converts the input byte array into Base64 format using a custom algorithm.Options Compared
The benchmark compares the performance of these two approaches:
btoa
(built-in function)base64ArrayBuffer
implementationPros and Cons
btoa
Functionbase64ArrayBuffer
ImplementationLibrary and Purpose
The btoa
function is a built-in function in JavaScript, introduced in ECMAScript 5. Its purpose is to encode an array of Unicode code points into Base64 format.
Special JS Feature or Syntax
None mentioned.
Other Considerations
When choosing between these two approaches, consider the following:
btoa
function has a simpler implementation and is less prone to errors.btoa
is part of the Web API, it's supported by most modern browsers. However, older browsers may not support it.Alternatives
If you're interested in exploring alternative approaches, consider:
base64-encode
) for encoding and decoding.Keep in mind that these alternatives might introduce additional complexity or performance overhead.