Skip to content

Instantly share code, notes, and snippets.

@crabmusket
Last active July 12, 2022 14:13
Show Gist options
  • Save crabmusket/2c8c6e692974edd56cd6ab8fee14addd to your computer and use it in GitHub Desktop.
Save crabmusket/2c8c6e692974edd56cd6ab8fee14addd to your computer and use it in GitHub Desktop.
Benchmarking msgpack versus JSON

Run this code using Deno:

deno run https://gist.githubusercontent.com/crabmusket/2c8c6e692974edd56cd6ab8fee14addd/raw/869958a7094daf17b36be6ac078aa0eafb4b0a9d/benchmark.js

It will prompt you for two network permissions, to download the sample data files.

An example of results from my laptop:

JSON with lots of strings:
┌───────┬──────────────────┬──────────────────────────────────────────┐
│ (idx) │ method           │ result                                   │
├───────┼──────────────────┼──────────────────────────────────────────┤
│     0 │ "JSON.stringify" │ "53,458 ops/sec ±5.42% (150004 samples)" │
│     1 │ "msgpack.encode" │ "17,388 ops/sec ±5.25% (50252 samples)"  │
└───────┴──────────────────┴──────────────────────────────────────────┘

GeoJSON with lots of numbers:
┌───────┬──────────────────┬───────────────────────────────────────┐
│ (idx) │ method           │ result                                │
├───────┼──────────────────┼───────────────────────────────────────┤
│     0 │ "JSON.stringify" │ "460 ops/sec ±1.84% (1389 samples)"   │
│     1 │ "msgpack.encode" │ "1,554 ops/sec ±4.26% (4640 samples)" │
└───────┴──────────────────┴───────────────────────────────────────┘

GeoJSON with flattened arrays:
┌───────┬──────────────────┬──────────────────────────────────────┐
│ (idx) │ method           │ result                               │
├───────┼──────────────────┼──────────────────────────────────────┤
│     0 │ "JSON.stringify" │ "429 ops/sec ±1.82% (1295 samples)"  │
│     1 │ "msgpack.encode" │ "2,762 ops/sec ±4.7% (8219 samples)" │
└───────┴──────────────────┴──────────────────────────────────────┘

GeoJSON with Float64Arrays:
┌───────┬──────────────────┬─────────────────────────────────────────┐
│ (idx) │ method           │ result                                  │
├───────┼──────────────────┼─────────────────────────────────────────┤
│     0 │ "JSON.stringify" │ "359 ops/sec ±2.16% (1081 samples)"     │
│     1 │ "msgpack.encode" │ "13,441 ops/sec ±5.15% (39463 samples)" │
└───────┴──────────────────┴─────────────────────────────────────────┘

This just goes to show that your data, and its layout, can have significant effects on benchmarks.

import bench from "https://raw.githubusercontent.com/crabmusket/nodemark/deno/index.js";
import { encode } from "https://deno.land/x/[email protected]/mod.ts";
const res1 = await fetch(
"https://raw.githubusercontent.com/endel/msgpack-benchmark/master/sample-large.json",
);
const sample = await res1.json();
const res2 = await fetch(
"https://geojson-maps.ash.ms/countries/50m/USA.geojson",
);
const usa = await res2.json();
const one = bench(
() => JSON.stringify(sample),
);
const two = bench(
() => encode(sample),
);
console.log("\nResults:\n");
console.log("JSON with lots of strings:");
console.table([
{ method: "JSON.stringify", result: one.toString() },
{ method: "msgpack.encode", result: two.toString() },
]);
console.log();
const three = bench(
() => JSON.stringify(usa),
);
const four = bench(
() => encode(usa),
);
console.log("GeoJSON with lots of numbers:");
console.table([
{ method: "JSON.stringify", result: three.toString() },
{ method: "msgpack.encode", result: four.toString() },
]);
console.log();
const usaFlat = {
properties: usa.properties,
geometry: usa.geometry.coordinates.map((poly) => poly.flat(Infinity)),
};
const five = bench(
() => JSON.stringify(usaFlat),
);
const six = bench(
() => encode(usaFlat),
);
console.log("GeoJSON with flattened arrays:");
console.table([
{ method: "JSON.stringify", result: five.toString() },
{ method: "msgpack.encode", result: six.toString() },
]);
console.log();
const usaPacked = {
properties: usa.properties,
geometry: usa.geometry.coordinates.map((poly) =>
new Float64Array(poly.flat(Infinity))
),
};
const seven = bench(
() => JSON.stringify(usaPacked),
);
const eight = bench(
() => encode(usaPacked),
);
console.log("GeoJSON with Float64Arrays:");
console.table([
{ method: "JSON.stringify", result: seven.toString() },
{ method: "msgpack.encode", result: eight.toString() },
]);
console.log();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment