Skip to content

Commit

Permalink
publish benchmarks
Browse files Browse the repository at this point in the history
  • Loading branch information
JairusSW committed Jun 3, 2024
1 parent edc0e8b commit 713a1c9
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 109 deletions.
80 changes: 38 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,53 +84,49 @@ If you use this project in your codebase, consider dropping a [star](https://git

Run or view the benchmarks [here](https://github.com/JairusSW/as-json/tree/master/bench)

Below are benchmark results comparing JavaScript, WAVM (WebAssembly Virtual Machine), and Wasmtime environments.
Below are benchmark results comparing JavaScript's built-in JSON implementation and `JSON-AS`

JavaScript Results
My library beats JSON (written in C++) on all counts *and*, I see many places where I can pull at least a 60% uplift in performance if I implement it.

NodeJS v20.5.1 - TinyBench v2.5.0 (V8)
```
┌───────────────────────────┬───────────────┐
│ Task Name │ ops / sec │
├───────────────────────────┼───────────────┤
│ 'Stringify Object (Vec3)' │ '1,191,221' │
│ 'Parse Object (Vec3)' │ '897,759' │
│ 'Stringify Number Array' │ '1,552,255' │
│ 'Parse Number Array' │ '1,225,325' │
│ 'Stringify String' │ '1,761,011' │
│ 'Parse String' │ '80,845' │
└───────────────────────────┴───────────────┘
```
**Serialize String**

AssemblyScript Results
- Value: "hello world"

WAVM v0.0.0-prerelease - as-bench v0.0.0-alpha (LLVM)
```
┌───────────────────────────┬───────────────┐
│ Task Name │ ops / sec │
├───────────────────────────┼───────────────┤
│ 'Stringify Object (Vec3)' │ '6,270,322' │
│ 'Parse Object (Vec3)' │ '8,000,195' |
│ 'Stringify Number Array' │ '6,664,937' │
│ 'Parse Number Array' │ '6,557,357' │
│ 'Stringify String' │ '6,946,947' │
│ 'Parse String' │ '10,952,502' │
└───────────────────────────┴───────────────┘
```
JavaScript: 28,629,598 ops/s

Wasmtime v11.0.1 - as-bench v0.0.0-alpha (Cranelift)
```
┌───────────────────────────┬───────────────┐
│ Task Name │ ops / sec │
├───────────────────────────┼───────────────┤
│ 'Stringify Object (Vec3)' │ '2,038,684' │
│ 'Parse Object (Vec3)' │ '4,623,337' |
│ 'Stringify Number Array' │ '2,500,947' │
│ 'Parse Number Array' │ '2,959,180' │
│ 'Stringify String' │ '3,236,896' │
│ 'Parse String' │ '5,634,594' │
└───────────────────────────┴───────────────┘
```
AssemblyScript: 64,210,666 ops/s

**Serialize Integer**

- Value 12345

JavaScript: 31,562,431 ops/s

AssemblyScript: 48,035,001 ops/s

**Serialize Float**

- Value 1.2345

JavaScript: 15,977,278 ops/s

AssemblyScript: 20,322,939 ops/s

**Serialize Set Theoretical Representation**

- Value [[],[[]],[[],[[]]]]

JavaScript: 8,998,624 ops/s

AssemblyScript: 34,453,102 ops/s

**Parse Integer**

- Value: "12345"

JavaScript: 34,647,886 ops/s

AssemblyScript: 254,640,930 ops/s

## Issues

Expand Down
84 changes: 20 additions & 64 deletions assembly/bench/bench.ts
Original file line number Diff line number Diff line change
@@ -1,82 +1,38 @@
import { JSON } from "..";
import { _deserializeString, deserializeString } from "../deserialize/string";
import { Sink } from "../src/sink";

import { bench, blackbox } from "as-bench/assembly/bench";
import { __atoi_fast, __atoi_fast_safe } from "../src/util";
import { serializeUnknown } from "../serialize/unknown";
import { Sink } from "../src/sink";
import { JSON } from "..";

const set = JSON.Value.from([
JSON.Value.from([]),
JSON.Value.from([
JSON.Value.from([])
JSON.Value.from([])
]),
JSON.Value.from([
JSON.Value.from([]),
JSON.Value.from([
JSON.Value.from([])
]),
JSON.Value.from([]),
JSON.Value.from([
JSON.Value.from([])
]),
]),
]);

@unmanaged
class Vec3 {
x: f64;
y: f64;
z: f64;
@inline __JSON_Serialize(out: Sink | null = null): Sink {
if (!out) {
out = Sink.withCapacity(25);
}

out.write(this.__JSON_Serialize_Unsafe());

return out;
}
@inline __JSON_Serialize_Unsafe(): string {
return `{"x":${JSON.serialize<f64>(this.x)},"y":${JSON.serialize<f64>(this.y)},"z":${JSON.serialize<f64>(this.z)}}`;
}
}

const vec: Vec3 = {
x: 3.4,
y: 1.2,
z: -5.6
}

const map = new Map<string, JSON.Value>();
map.set("x", JSON.Value.from<f64>(3.4));
map.set("y", JSON.Value.from<f64>(1.2));
map.set("z", JSON.Value.from<f64>(-5.6));
/*
bench("Serialize Set Theoretical Representation", () => {
blackbox<Sink>(serializeUnknown(set));
});
bench("Serialize Vector 3 Struct", () => {
blackbox<string>(vec.__JSON_Serialize_Unsafe());
});
bench("Serialize String (Sink)", () => {
blackbox<Sink>(JSON.serialize<string>("hello world"));
blackbox<Sink>(JSON.serialize(set));
});
bench("Serialize String (No Sink)", () => {
blackbox<string>(JSON.serialize<string>("hello world").toString());
/*bench("Serialize Float", () => {
blackbox<Sink>(JSON.serialize<f64>(1.2345));
});
bench("Parse String (Raw)", () => {
blackbox<string>(_deserializeString("\"hello world\""));
bench("Serialize Float32", () => {
blackbox<Sink>(JSON.serialize<f32>(1.2345));
});
bench("Parse String (Product)", () => {
blackbox<ProductValue>(JSON.parse<string>("\"hello world\""));
bench("Serialize String", () => {
blackbox<Sink>(JSON.serialize("hello world"));
});
bench("Parse String (Unwrap)", () => {
blackbox<string>(JSON.parse<string>("\"hello world\"").unwrap<string>());
});*/
bench("ATOI (Unsafe): " + __atoi_fast<u32>("1234567890").toString(), () => {
blackbox<u32>(__atoi_fast<u32>("1234567890"));
bench("Serialize Integer", () => {
blackbox<Sink>(JSON.serialize(12345));
});
bench("ATOI (Safe): " + __atoi_fast_safe<u32>("1234567890").toString(), () => {
blackbox<u32>(__atoi_fast_safe<u32>("1234567890"));
});
bench("empty", () => {})
bench("Parse Number: " + __atoi_fast<u32>("12345").toString(), () => {
blackbox<u32>(__atoi_fast<u32>("12345"));
});*/
27 changes: 27 additions & 0 deletions bench.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import Benchmark from "benchmark";
const suite = new Benchmark.Suite;

suite.add("Serialize Set Theoretical Representation", () => {
JSON.stringify([[],[[]],[[],[[]]]]);
});
/*
suite.add("Serialize Float", () => {
JSON.stringify(1.2345);
});
suite.add("Serialize Integer", () => {
JSON.stringify(12345);
});
suite.add("Serialize String", () => {
JSON.stringify("hello world");
});
suite.add("Parse Number", () => {
JSON.parse("12345");
});
*/
suite.on("cycle", (cycle) => {
console.log(cycle.target.toString());
});


suite.run();
1 change: 1 addition & 0 deletions index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { JSON } from "./assembly/src/json";

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"build:test": "asc assembly/test.ts -o build/test.wasm --transform ./transform --config ./node_modules/@assemblyscript/wasi-shim/asconfig.json",
"build:bench": "asc assembly/bench/bench.ts -o build/bench.wasm --config ./node_modules/@assemblyscript/wasi-shim/asconfig.json --optimizeLevel 3 --converge --exportRuntime --runtime stub",
"bench:wasmtime": "wasmtime ./build/bench.wasm",
"bench:wavm": "wavm run ./build/bench.wasm",
"bench:wasmer": "wasmer run ./build/bench.wasm --llvm",
"build:transform": "tsc -p ./transform",
"test:wasmtime": "wasmtime ./build/test.wasm",
"test:wavm": "wavm run ./build/test.wasm",
Expand All @@ -32,6 +32,7 @@
"@as-pect/cli": "^8.1.0",
"@as-tral/cli": "^3.0.2",
"@assemblyscript/wasi-shim": "^0.1.0",
"@types/benchmark": "^2.1.5",
"as-bench": "^0.0.0-alpha",
"as-test": "JairusSW/as-test#03e96e7",
"assemblyscript": "^0.27.22",
Expand All @@ -40,14 +41,13 @@
"kati": "^0.6.2",
"microtime": "^3.1.1",
"prettier": "^3.1.1",
"tinybench": "^2.5.1",
"tinybench": "^2.8.0",
"typescript": "^5.3.3",
"visitor-as": "^0.11.4"
},
"dependencies": {
"as-container": "^0.8.0",
"as-string-sink": "^0.5.3",
"as-test": "JairusSW/as-test",
"as-variant": "^0.4.1",
"as-virtual": "^0.1.9"
},
Expand Down

0 comments on commit 713a1c9

Please sign in to comment.