function get1024Bytes(n) {
const bytes = new Uint8Array(n * 1024);
for (let i = 0; i < bytes.length; i += 1) {
bytes[i] = Math.random() * 0xff;
}
return bytes;
}
const bytes = get1024Bytes(1024);
/*
Note that Function.prototype.apply() has a limit, so not using it to creat binary string here for convenience.
To use it, split the array into smaller chunks first.
String.fromCodePoint.apply(null, bytes); // bytes.length should not exceed the maximum
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
*/
const binString = Array.from(bytes, (byte) => String.fromCodePoint(byte)).join("");
return Uint8Array.from(binString, (m) => m.codePointAt(0));
return Uint8Array.from(binString, (m) => m.charCodeAt(0));
const bytes = new Uint8Array(binString.length);
for (let i = 0; i < bytes.length; i += 1) {
bytes[i] = binString[i].codePointAt(0);
}
return bytes;
const bytes = new Uint8Array(binString.length);
for (let i = 0; i < bytes.length; i += 1) {
bytes[i] = binString[i].charCodeAt(0);
}
return bytes;
const QUANTUM = 128;
const bytes = new Uint8Array(binString.length);
for (let i = 0; i < binString.length; i += QUANTUM) {
let j = i;
for (const b of Uint8Array.from(binString.slice(i, i + QUANTUM), (m) => m.codePointAt(0))) {
bytes[j] = b;
j += 1;
}
}
return bytes;
const QUANTUM = 128;
const bytes = new Uint8Array(binString.length);
for (let i = 0; i < binString.length; i += QUANTUM) {
let j = i;
for (const b of Uint8Array.from(binString.slice(i, i + QUANTUM), (m) => m.charCodeAt(0))) {
bytes[j] = b;
j += 1;
}
}
return bytes;
const QUANTUM = 32768;
const bytes = new Uint8Array(binString.length);
for (let i = 0; i < binString.length; i += QUANTUM) {
let j = i;
for (const b of Uint8Array.from(binString.slice(i, i + QUANTUM), (m) => m.codePointAt(0))) {
bytes[j] = b;
j += 1;
}
}
return bytes;
const QUANTUM = 32768;
const bytes = new Uint8Array(binString.length);
for (let i = 0; i < binString.length; i += QUANTUM) {
let j = i;
for (const b of Uint8Array.from(binString.slice(i, i + QUANTUM), (m) => m.charCodeAt(0))) {
bytes[j] = b;
j += 1;
}
}
return bytes;
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
Uint8Array.from + codePointAt | |
Uint8Array.from + charCodeAt | |
for-loop + codePointAt | |
for-loop + charCodeAt | |
for-loop + Uint8Array.from + codePointAt (small chunk) | |
for-loop + Uint8Array.from + charCodeAt (small chunk) | |
for-loop + Uint8Array.from + codePointAt (big chunk) | |
for-loop + Uint8Array.from + charCodeAt (big chunk) |
Test name | Executions per second |
---|---|
Uint8Array.from + codePointAt | 12.1 Ops/sec |
Uint8Array.from + charCodeAt | 12.9 Ops/sec |
for-loop + codePointAt | 9.8 Ops/sec |
for-loop + charCodeAt | 8.5 Ops/sec |
for-loop + Uint8Array.from + codePointAt (small chunk) | 8.7 Ops/sec |
for-loop + Uint8Array.from + charCodeAt (small chunk) | 8.7 Ops/sec |
for-loop + Uint8Array.from + codePointAt (big chunk) | 9.0 Ops/sec |
for-loop + Uint8Array.from + charCodeAt (big chunk) | 8.9 Ops/sec |
The provided benchmark tests the performance of various methods for converting a binary string into a Uint8Array
in JavaScript. The benchmark evaluates several approaches using different character extraction methods and chunk sizes.
Uint8Array.from + codePointAt
:
Uint8Array.from()
method, which constructs a typed array from an array-like object. It uses codePointAt()
to retrieve the Unicode code point of each character.Uint8Array.from()
.Uint8Array.from + charCodeAt
:
charCodeAt()
, which returns the UTF-16 code unit at a specified index.codePointAt()
for characters in the Basic Multilingual Plane (BMP).for-loop + codePointAt
:
Uint8Array
by calling codePointAt()
on each character.for-loop + charCodeAt
:
charCodeAt()
.Chunked Approaches (Small and Big Chunks):
QUANTUM
constant), extracting characters in Uint8Array.from()
calls within nested loops. Testing includes both codePointAt()
and charCodeAt()
versions for small and large chunk sizes.Uint8Array.from()
. Performance may diminish with high QUANTUM
values.The benchmark utilizes the built-in Uint8Array
class, which is part of the Arrays and Typed Arrays API in JavaScript for representing an array of 8-bit unsigned integers. This is particularly useful for handling binary data.
codePointAt()
: This is a JavaScript string method that returns an integer representing the Unicode code point value of the character at the provided index. It can handle characters outside the standard BMP, which makes it more powerful for Unicode manipulation.
charCodeAt()
: This method returns the UTF-16 code unit at a specified index in the string. It is limited to the BMP and can yield incorrect values for characters beyond this range.
When dealing with string to binary conversions in JavaScript, alternative methods could include:
TextEncoder: This modern API allows encoding strings into Uint8Array
. It's a high-level and efficient way to convert strings, especially supporting various text encodings.
const encoder = new TextEncoder();
const byteArray = encoder.encode(binString);
Manual Conversion: Writing custom conversion functions can provide flexibility at potentially lower performance if not optimized correctly.
Other Libraries: Libraries like buffer
in Node.js provide different methods for buffer manipulation and can facilitate binary encoding and decoding.
By applying various approaches to test performance, developers can ascertain the most efficient means of converting binary strings into byte arrays based on the specific needs and target environments of their applications.