var ab = new ArrayBuffer(70*1024);
var uint8 = new Uint8Array(ab);
for (var i = 0; i < ab.byteLength; i++) {
uint8[i] = i % 256;
}
var expected = window.btoa(String.fromCharCode.apply(null, uint8));
function byteArrayToString(bytes) {
var CHUNK_SIZE = 8*1024;
if (bytes.length <= CHUNK_SIZE)
return String.fromCharCode.apply(null, bytes);
var str = '';
for (var i = 0; i < bytes.length; i += CHUNK_SIZE)
str += String.fromCharCode.apply(null, bytes.slice(i, i+CHUNK_SIZE));
return str;
}
function validate(res){
if (res !== expected)
throw "expected=" + expected + " but got " + res;
}
function uint6ToB64(nUint6) {
return nUint6 < 26 ?
nUint6 + 65
: nUint6 < 52 ?
nUint6 + 71
: nUint6 < 62 ?
nUint6 - 4
: nUint6 === 62 ?
43
: nUint6 === 63 ?
47
:
65;
};
function bytesToBase64(aBytes) {
var eqLen = (3 - (aBytes.length % 3)) % 3, sB64Enc = "";
for (var nMod3, nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) {
nMod3 = nIdx % 3;
nUint24 |= aBytes[nIdx] << (16 >>> nMod3 & 24);
if (nMod3 === 2 || aBytes.length - nIdx === 1) {
sB64Enc += String.fromCharCode(uint6ToB64(nUint24 >>> 18 & 63), uint6ToB64(nUint24 >>> 12 & 63), uint6ToB64(nUint24 >>> 6 & 63), uint6ToB64(nUint24 & 63));
nUint24 = 0;
}
}
return eqLen === 0 ?
sB64Enc
:
sB64Enc.substring(0, sB64Enc.length - eqLen) + (eqLen === 1 ? "=" : "==");
};
var bin = String.fromCharCode.apply(null, uint8);
var res = window.btoa(bin)
validate(res)
var bin = '';
for (var i = 0; i < uint8.byteLength; i++)
bin += String.fromCharCode(uint8[i]);
var res = window.btoa(bin)
validate(res)
var res = bytesToBase64(uint8)
validate(res)
var bin = [];
for (var i = 0; i < uint8.byteLength; i++)
bin.push(String.fromCharCode(uint8[i]));
var res = window.btoa(bin.join(''))
validate(res)
var bin = byteArrayToString(uint8);
var res = window.btoa(bin)
validate(res)
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
String.fromCharCode.apply | |
String.fromCharCode | |
bytesToBase64 | |
arr join | |
byteArrayToString |
Test name | Executions per second |
---|---|
String.fromCharCode.apply | 1383.3 Ops/sec |
String.fromCharCode | 680.5 Ops/sec |
bytesToBase64 | 221.4 Ops/sec |
arr join | 977.0 Ops/sec |
byteArrayToString | 2129.1 Ops/sec |
Let's break down the test cases and explain what is being tested.
Overview
The benchmark measures the performance of converting an ArrayBuffer
to a base64 string in different ways, using various JavaScript functions.
Test Cases
String.fromCharCode.apply(null, uint8)
syntax to create a string from the Uint8Array
. The resulting string is then passed to the window.btoa()
function.String.fromCharCode(uint8[i])
.bytesToBase64
function to convert the Uint8Array
to a base64 string.bin.join('')
, before passing it to window.btoa()
.byteArrayToString
function to convert the Uint8Array
to a string, which is then passed to window.btoa()
.Options Compared
The benchmark compares the performance of five different approaches:
String.fromCharCode.apply(null, uint8)
String.fromCharCode(uint8[i])
bytesToBase64
functionbin.join('')
byteArrayToString
functionPros and Cons of Each Approach
String.fromCharCode(uint8[i])
can lead to slower performance due to string creation overhead.bin.join('')
can lead to slower performance due to array manipulation overhead.byteArrayToString
function is designed specifically for converting Uint8Array
to strings, but its implementation details are not provided in the benchmark.Latest Benchmark Results
The latest benchmark results show the executions per second for each test case across different browsers and platforms. The top performer is the String.fromCharCode.apply
approach, followed by the custom bytesToBase64
function.
In summary, the benchmark measures the performance of converting an ArrayBuffer
to a base64 string in different ways, using various JavaScript functions. The results show that the built-in String.fromCharCode.apply
method is likely to be the fastest, while custom approaches like bytesToBase64
and byteArrayToString
might offer competitive performance.