Last active
February 9, 2024 09:00
-
-
Save jridgewell/f7ee4cec9df6f49e404d44ca8d5d3de8 to your computer and use it in GitHub Desktop.
encodeInto with subarrays vs offsets (https://jsbench.github.io/#f7ee4cec9df6f49e404d44ca8d5d3de8) #jsbench #jsperf
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"/> | |
<title>encodeInto with subarrays vs offsets</title> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/benchmark/1.0.0/benchmark.min.js"></script> | |
<script src="./suite.js"></script> | |
</head> | |
<body> | |
<h1>Open the console to view the results</h1> | |
<h2><code>cmd + alt + j</code> or <code>ctrl + alt + j</code></h2> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict"; | |
(function (factory) { | |
if (typeof Benchmark !== "undefined") { | |
factory(Benchmark); | |
} else { | |
factory(require("benchmark")); | |
} | |
})(function (Benchmark) { | |
var suite = new Benchmark.Suite; | |
Benchmark.prototype.setup = function () { | |
// Change these to adjust how many subarray we'll make | |
const LEN = 10_000; | |
const MUL = 4; | |
console.assert(LEN % MUL === 0); | |
// - - - - - | |
const readBytes = MUL * 3; | |
const writeBytes = MUL * 5; | |
const data = "xx€".repeat(LEN); | |
const output = new Uint8Array(5 * LEN); | |
const subarrays = new Array(LEN / MUL); | |
const encoder = new TextEncoder(); | |
for (let i = 0; i < subarrays.length; i++) { | |
subarrays[i] = output.subarray(i * writeBytes, (i + 1) * writeBytes); | |
} | |
function encodeInto(input, readStart, readEnd, into, writeStart) { | |
let i = readStart; | |
let j = writeStart; | |
while (i < readEnd) { | |
let c = input.charCodeAt(i++); | |
if (c < 0x80) { | |
into[j++] = c; | |
} else if (c < 0x800) { | |
into[j++] = 0b1100_0000 | (c >> 6); | |
into[j++] = 0b1000_0000 | (c >> 0b0011_1111); | |
} else if (c < 0xd800 || c >= 0xe000) { | |
into[j++] = 0b1110_0000 | (c >> 12); | |
into[j++] = 0b1000_0000 | ((c >> 6) & 0b0011_1111); | |
into[j++] = 0b1000_0000 | (c & 0b0011_1111); | |
} else { | |
const c2 = input.charCodeAt(i++); | |
c = 0x10000 + (((c & 0x3ff) << 10) | (c2 & 0x3ff)); | |
into[j++] = 0b1111_0000 | (c >> 18); | |
into[j++] = 0b1000_0000 | ((c >> 12) & 0b0011_1111); | |
into[j++] = 0b1000_0000 | ((c >> 6) & 0b0011_1111); | |
into[j++] = 0b1000_0000 | (c & 0b0011_1111); | |
} | |
} | |
return { read: i - readStart, written: j - writeStart }; | |
} | |
}; | |
suite.add("TextEncoder (on-the-fly subarrays)", function () { | |
// TextEncoder (on-the-fly subarrays) | |
for (let read = 0, written = 0; read < data.length; ) { | |
const stats = encoder.encodeInto( | |
data.substring(read, read + readBytes), | |
output.subarray(written, written + writeBytes), | |
); | |
read += stats.read; | |
written += stats.written; | |
} | |
}); | |
suite.add("TextEncoder (premade subarrays)", function () { | |
// TextEncoder (premade subarrays) | |
for (let read = 0, w = 0; read < data.length; w++) { | |
const stats = encoder.encodeInto( | |
data.substring(read, read + readBytes), | |
subarrays[w], | |
); | |
read += stats.read; | |
} | |
}); | |
suite.add("custom encodeInto (on-the-fly subarrays, substrings)", function () { | |
// custom encodeInto (on-the-fly subarrays, substrings) | |
for (let read = 0, written = 0; read < data.length; ) { | |
const stats = encodeInto( | |
data.substring(read, read + readBytes), | |
0, | |
readBytes, | |
output.subarray(written, written + writeBytes), | |
0, | |
); | |
read += stats.read; | |
written += stats.written; | |
} | |
}); | |
suite.add("custom encodeInto (premade subarrays, substrings)", function () { | |
// custom encodeInto (premade subarrays, substrings) | |
for (let read = 0, w = 0; read < data.length; w++) { | |
const stats = encodeInto( | |
data.substring(read, read + readBytes), | |
0, | |
readBytes, | |
subarrays[w], | |
0, | |
); | |
read += stats.read; | |
} | |
}); | |
suite.add("custom encodeInto (write offset, substrings)", function () { | |
// custom encodeInto (write offset, substrings) | |
for (let read = 0, written = 0; read < data.length; ) { | |
const stats = encodeInto( | |
data.substring(read, read + readBytes), | |
0, | |
readBytes, | |
output, | |
written, | |
); | |
read += stats.read; | |
written += stats.written; | |
} | |
}); | |
suite.add("custom encodeInto (on-the-fly subarrays, read offset)", function () { | |
// custom encodeInto (on-the-fly subarrays, read offset) | |
for (let read = 0, written = 0; read < data.length; ) { | |
const stats = encodeInto( | |
data, | |
read, | |
read + readBytes, | |
output.subarray(written, written + writeBytes), | |
0, | |
); | |
read += stats.read; | |
written += stats.written; | |
} | |
}); | |
suite.add("custom encodeInto (premade subarrays, read offset)", function () { | |
// custom encodeInto (premade subarrays, read offset) | |
for (let read = 0, w = 0; read < data.length; w++) { | |
const stats = encodeInto( | |
data, | |
read, | |
read + readBytes, | |
subarrays[w], | |
0, | |
); | |
read += stats.read; | |
} | |
}); | |
suite.add("custom encodeInto (write offset, read offset)", function () { | |
// custom encodeInto (write offset, read offset) | |
for (let read = 0, written = 0; read < data.length; ) { | |
const stats = encodeInto( | |
data, | |
read, | |
read + readBytes, | |
output, | |
written, | |
); | |
read += stats.read; | |
written += stats.written; | |
} | |
}); | |
suite.on("cycle", function (evt) { | |
console.log(" - " + evt.target); | |
}); | |
suite.on("complete", function (evt) { | |
console.log(new Array(30).join("-")); | |
var results = evt.currentTarget.sort(function (a, b) { | |
return b.hz - a.hz; | |
}); | |
results.forEach(function (item) { | |
console.log((idx + 1) + ". " + item); | |
}); | |
}); | |
console.log("encodeInto with subarrays vs offsets"); | |
console.log(new Array(30).join("-")); | |
suite.run(); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment