TextDecoder (v9)

Revision 9 of this benchmark created on


Setup

const utf8Decoder = new TextDecoder();
const data = new Uint8Array(100_000);
const code = "x".charCodeAt(0);

// Initialize the array to a valid ASCII value
// to ensure that NULL isn't doing anything
// weird here.
for (var i = 0; i < data.length; i++) {
  data[i] = code;
}

function DecodeUtf8(array) {
  let buffer = new Array(array.length);
  let j = 0;
  let end = array.length;
  for (let i = 0; i < end;) {
    let c = array[i++];
    if (0x7F >= c) {
      buffer[j++] = String.fromCharCode(c);
    } else if (0xDF >= c) {
      if (1 > end - i) throw new Error("invalid wtf8");
      var c2 = array[i++];
      buffer[j++] = String.fromCharCode(((c & 0x1F) << 6) | (c2 & 0x3F));
    } else if (0xEF >= c) {
      if (2 > end - i) throw new error("invalid wtf8");
      c2 = array[i++];
      var c3 = array[i++];
      buffer[j++] = String.fromCharCode(((c & 0xF) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F));
    } else if (0xF7 >= c) {
      if (3 > end - start) throw new error("invalid wtf8");
      c2 = array[i++];
      c3 = array[i++];
      var c4 = array[i++];
      buffer[j++] = String.fromCodePoint(((c & 0x7) << 18) | ((c2 & 0x3F) << 12) |
        ((c3 & 0x3F) << 6) | (c4 & 0x3F));
    } else {
      throw new error("invalid wtf8");
    }
  }
  while (j > buffer.length) buffer.pop();
  return buffer.join("");
}

Test runner

Ready to run.

Testing in
TestOps/sec
Many small calls
var results = [];
var ofs = 0;
for (var i = 0; i < 10_000; i++, ofs += 10) {
  results.push(utf8Decoder.decode(data.subarray(ofs, ofs + 10)));
}
if (results.length != 10_000) throw "bad";
ready
One big call
var results = [];
const str = utf8Decoder.decode(data);
var ofs = 0;
for (var i = 0; i < 10_000; i++, ofs += 10) {
  results.push(str.substring(ofs, ofs + 10));
}
if (results.length != 10_000) throw "bad";
ready
Custom decoder (small calls)
var results = [];
var ofs = 0;
for (var i = 0; i < 10_000; i++, ofs += 10) {
  results.push(DecodeUtf8(data.subarray(ofs, ofs + 10)));
}
if (results.length != 10_000) throw "bad";
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.