Skip to content

Commit

Permalink
Add a benchmark for TypedArray with zero-copy extension
Browse files Browse the repository at this point in the history
  • Loading branch information
EddiG committed Feb 3, 2025
1 parent fbcd36b commit 46af895
Showing 1 changed file with 61 additions and 15 deletions.
76 changes: 61 additions & 15 deletions benchmark/msgpack-benchmark.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,45 @@
"use strict";
require("ts-node/register");
const Benchmark = require("benchmark");
const fs = require("fs");
const msgpack = require("../src");

const msgpackEncode = require("..").encode;
const msgpackDecode = require("..").decode;
const ExtensionCodec = require("..").ExtensionCodec;

const extensionCodec = new ExtensionCodec();
extensionCodec.register({
type: 0x01,
encode: (object) => {
if (object instanceof Float32Array) {
return (pos) => {
const bpe = Float32Array.BYTES_PER_ELEMENT;
const padding = 1 + ((bpe - ((pos + 1) % bpe)) % bpe);
const data = new Uint8Array(object.buffer);
const result = new Uint8Array(padding + data.length);
result[0] = padding;
result.set(data, padding);
return result;
};
}
return null;
},
decode: (data) => {
const padding = data[0];
const bpe = Float32Array.BYTES_PER_ELEMENT;
const offset = data.byteOffset + padding;
const length = data.byteLength - padding;
return new Float32Array(data.buffer, offset, length / bpe);
},
});

const implementations = {
"@msgpack/msgpack": {
encode: require("..").encode,
decode: require("..").decode,
encode: msgpackEncode,
decode: msgpackDecode,
},
"@msgpack/msgpack (zero-copy extension)": {
encode: (data) => msgpackEncode(data, { extensionCodec }),
decode: (data) => msgpackDecode(data, { extensionCodec }),
},
"msgpack-lite": {
encode: require("msgpack-lite").encode,
Expand All @@ -21,28 +53,42 @@ const implementations = {
},
};

// exactly the same as:
// https://raw.githubusercontent.com/endel/msgpack-benchmark/master/sample-large.json
const sampleFiles = ["./sample-large.json"];
const samples = [
{
// exactly the same as:
// https://raw.githubusercontent.com/endel/msgpack-benchmark/master/sample-large.json
name: "./sample-large.json",
data: require("./sample-large.json"),
},
{
name: "Generated large Float32Array",
data: [
{
position: new Float32Array(1e3).fill(1.14),
},
],
},
];

function validate(name, data, encoded) {
if (JSON.stringify(data) !== JSON.stringify(implementations[name].decode(encoded))) {
throw new Error("Bad implementation: " + name);
}
return JSON.stringify(data) === JSON.stringify(implementations[name].decode(encoded));
}

for (const sampleFile of sampleFiles) {
const data = require(sampleFile);
for (const sample of samples) {
const { name: sampleName, data } = sample;
const encodeSuite = new Benchmark.Suite();
const decodeSuite = new Benchmark.Suite();

console.log("");
console.log("**" + sampleFile + ":** (" + JSON.stringify(data).length + " bytes in JSON)");
console.log("**" + sampleName + ":** (" + JSON.stringify(data).length + " bytes in JSON)");
console.log("");

for (const name of Object.keys(implementations)) {
implementations[name].toDecode = implementations[name].encode(data);
validate(name, data, implementations[name].toDecode);
if (!validate(name, data, implementations[name].toDecode)) {
console.log("Not supported by " + name);
continue;
}
encodeSuite.add("(encode) " + name, () => {
implementations[name].encode(data);
});
Expand All @@ -60,7 +106,7 @@ for (const sampleFile of sampleFiles) {

console.log("");

decodeSuite.on("cycle", function(event) {
decodeSuite.on("cycle", (event) => {
console.log(String(event.target));
});

Expand Down

0 comments on commit 46af895

Please sign in to comment.