-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
1 parent
4962804
commit b3f15f5
Showing
143 changed files
with
14,179 additions
and
5,423 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { createRequire } from "node:module"; | ||
|
||
import { spawn } from "child_process"; | ||
import { PluginBuild } from "esbuild"; | ||
import kill from "tree-kill"; | ||
|
||
let runningProcess: ReturnType<typeof spawn> | undefined; | ||
|
||
export const rebuildOnDependencyChangesPlugin = { | ||
name: "watch-dependencies", | ||
setup(build: PluginBuild) { | ||
build.onResolve({ filter: /.*/ }, (args) => { | ||
// Include dependent packages in the watch list | ||
if (args.kind === "import-statement") { | ||
if (!args.path.startsWith(".")) { | ||
const require = createRequire(args.resolveDir); | ||
let resolved; | ||
try { | ||
resolved = require.resolve(args.path); | ||
} catch { | ||
return; | ||
} | ||
return { | ||
external: true, | ||
watchFiles: [resolved], | ||
}; | ||
} | ||
} | ||
}); | ||
build.onEnd(async () => { | ||
console.log("Build finished. (Re)starting process"); | ||
if (runningProcess) { | ||
await new Promise<void>((resolve) => { | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
kill(runningProcess!.pid!, "SIGTERM", (err) => { | ||
resolve(); | ||
}); | ||
}); | ||
} | ||
runningProcess = spawn("npm", ["run", "start-server"], { | ||
stdio: "inherit", | ||
}); | ||
}); | ||
}, | ||
}; |
This file contains 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
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# Networked DOM Protocol Benchmarks | ||
|
||
This directory contains a set of benchmarks for the Networked DOM Protocol encoding and decoding compared with JSON. | ||
|
||
As of writing the benchmarks show that the binary encoding is faster and smaller than JSON on a test data set. | ||
|
||
Notes: | ||
- The test data set uses expressive key names which are therefore included in the JSON output (field names are not included in the binary encoding). | ||
- The test data set does not use multi-byte characters which is more representative of the data that the protocol is used for. (However the binary encoding is still likely to be faster even in this case). | ||
|
||
## Encoding Results | ||
|
||
``` | ||
Ran on Node v20.11.1 on Apple M1 Max 16" MacBook Pro | ||
Binary x 947 ops/sec ±3.68% (92 runs sampled) | ||
JSON x 317 ops/sec ±0.52% (91 runs sampled) | ||
Fastest is Binary | ||
Binary byte length : 229153 | ||
JSON byte length : 703303 | ||
Binary is 0.3258 the length of JSON | ||
JSON is 3.0691 the length of Binary | ||
``` | ||
|
||
## Decoding Results | ||
|
||
``` | ||
Ran on Node v20.11.1 on Apple M1 Max 16" MacBook Pro | ||
Binary x 568 ops/sec ±0.40% (92 runs sampled) | ||
JSON x 245 ops/sec ±0.33% (90 runs sampled) | ||
Fastest is Binary | ||
``` |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"name": "@mml-io/protocol-benchmarks", | ||
"version": "0.18.1", | ||
"private": true, | ||
"type": "module", | ||
"scripts": { | ||
"build": "tsc --project ./tsconfig.json", | ||
"type-check": "tsc --noEmit", | ||
"lint": "eslint \"./**/*.{js,jsx,ts,tsx}\" --max-warnings 0", | ||
"lint-fix": "eslint \"./**/*.{js,jsx,ts,tsx}\" --fix", | ||
"benchmark-encoding": "npm run build && node ./build/encoding.js", | ||
"benchmark-decoding": "npm run build && node ./build/decoding.js" | ||
}, | ||
"devDependencies": { | ||
"@mml-io/networked-dom-protocol": "^0.18.1", | ||
"benchmark": "2.1.4", | ||
"@types/benchmark": "2.1.5" | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import { | ||
BufferReader, | ||
BufferWriter, | ||
encodeServerMessage, | ||
NetworkedDOMV02ServerMessage, | ||
} from "@mml-io/networked-dom-protocol"; | ||
import { decodeServerMessages } from "@mml-io/networked-dom-protocol"; | ||
import Benchmark from "benchmark"; | ||
|
||
import { prepareData } from "./prepare-data.js"; | ||
|
||
const data = prepareData(1000); | ||
|
||
const encodedData = data.map((message) => { | ||
const writer = new BufferWriter(256); | ||
encodeServerMessage(message, writer); | ||
return writer.getBuffer(); | ||
}); | ||
const encodedJSON = data.map((message) => JSON.stringify(message)); | ||
|
||
const suite = new Benchmark.Suite(); | ||
suite | ||
.add("Binary", function () { | ||
let totalLength = 0; | ||
for (const message of encodedData) { | ||
const bufferReader = new BufferReader(message); | ||
const decoded = decodeServerMessages(bufferReader); | ||
totalLength += (decoded[0] as NetworkedDOMV02ServerMessage).type.length; | ||
} | ||
if (totalLength <= 0) { | ||
throw new Error("Invalid total length"); | ||
} | ||
}) | ||
.add("JSON", function () { | ||
let totalLength = 0; | ||
for (const message of encodedJSON) { | ||
const decoded = JSON.parse(message); | ||
totalLength += decoded.type.length; | ||
} | ||
if (totalLength <= 0) { | ||
throw new Error("Invalid total length"); | ||
} | ||
}) | ||
// add listeners | ||
.on("cycle", (event: Benchmark.Event) => { | ||
console.log(String(event.target)); | ||
}) | ||
.on("complete", () => { | ||
console.log(`Fastest is ${suite.filter("fastest").map("name")}`); | ||
}) | ||
// run async | ||
.run({ async: true }); |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { BufferWriter, encodeServerMessage } from "@mml-io/networked-dom-protocol"; | ||
import Benchmark from "benchmark"; | ||
|
||
import { prepareData } from "./prepare-data.js"; | ||
|
||
let totalBinaryLength = 0; | ||
let totalJSONLength = 0; | ||
|
||
const data = prepareData(1000); | ||
const suite = new Benchmark.Suite(); | ||
suite | ||
.add("Binary", function () { | ||
let totalLength = 0; | ||
for (const message of data) { | ||
const writer = new BufferWriter(256); | ||
encodeServerMessage(message, writer); | ||
const encoded = writer.getBuffer(); | ||
totalLength += encoded.length; | ||
} | ||
if (totalLength <= 0) { | ||
throw new Error("Invalid total length"); | ||
} | ||
totalBinaryLength = totalLength; | ||
}) | ||
.add("JSON", function () { | ||
let totalLength = 0; | ||
for (const message of data) { | ||
const encoded = JSON.stringify(message); | ||
totalLength += encoded.length; | ||
} | ||
if (totalLength <= 0) { | ||
throw new Error("Invalid total length"); | ||
} | ||
totalJSONLength = totalLength; | ||
}) | ||
// add listeners | ||
.on("cycle", (event: Benchmark.Event) => { | ||
console.log(String(event.target)); | ||
}) | ||
.on("complete", () => { | ||
console.log(`Fastest is ${suite.filter("fastest").map("name")}`); | ||
|
||
console.log(`Binary byte length : ${totalBinaryLength}`); | ||
console.log(`JSON byte length : ${totalJSONLength}`); | ||
console.log(`Binary is ${(totalBinaryLength / totalJSONLength).toFixed(4)} the length of JSON`); | ||
console.log(`JSON is ${(totalJSONLength / totalBinaryLength).toFixed(4)} the length of Binary`); | ||
}) | ||
// run async | ||
.run({ async: true }); |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import { | ||
NetworkedDOMV02ChildrenAddedDiff, | ||
NetworkedDOMV02ServerMessage, | ||
} from "@mml-io/networked-dom-protocol"; | ||
|
||
export function prepareData(size: number): Array<NetworkedDOMV02ServerMessage> { | ||
const data: Array<NetworkedDOMV02ChildrenAddedDiff> = []; | ||
for (let i = 0; i < size; i++) { | ||
data.push({ | ||
type: "childrenAdded", | ||
nodeId: i + 1, | ||
previousNodeId: i + 2, | ||
addedNodes: [ | ||
{ | ||
type: "element", | ||
nodeId: i + 3, | ||
tag: "m-cube", | ||
attributes: [ | ||
["color" + i, "red"], | ||
["x", "1"], | ||
["y", "2"], | ||
["z", "3"], | ||
], | ||
children: [ | ||
{ | ||
type: "element", | ||
nodeId: i + 4, | ||
tag: "m-cube", | ||
attributes: [ | ||
["color" + i, "blue"], | ||
["x" + i, "4"], | ||
["y", "5"], | ||
["z", "6"], | ||
["rx" + i, "4"], | ||
["ry", "5"], | ||
["rz", "6"], | ||
], | ||
children: [], | ||
}, | ||
{ | ||
type: "element", | ||
nodeId: i + 5, | ||
tag: "m-cube", | ||
attributes: [ | ||
["color" + i, "blue"], | ||
["x" + i, "4"], | ||
["y", "5"], | ||
["z", "6"], | ||
["rx" + i, "4"], | ||
["ry", "5"], | ||
["rz", "6"], | ||
], | ||
children: [], | ||
}, | ||
{ | ||
type: "element", | ||
nodeId: i + 6, | ||
tag: "m-cube", | ||
attributes: [ | ||
["empty", ""], | ||
["color" + i, "blue"], | ||
["x" + i, "4"], | ||
["y", "5"], | ||
["z", "6"], | ||
["rx" + i, "4"], | ||
["ry", "5"], | ||
["rz", "6"], | ||
], | ||
children: [], | ||
}, | ||
], | ||
}, | ||
], | ||
}); | ||
} | ||
return data; | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"compilerOptions": { | ||
"target": "es5", | ||
"module": "ESNext", | ||
"moduleResolution": "node", | ||
"lib": ["es6"], | ||
"allowJs": true, | ||
"outDir": "build", | ||
"rootDir": "src", | ||
"strict": true, | ||
"noImplicitAny": true, | ||
"esModuleInterop": true, | ||
"skipLibCheck": true | ||
}, | ||
"include": ["src/**/*"], | ||
"exclude": ["src/**/*.spec.ts", "node_modules"] | ||
} |
This file contains 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
Oops, something went wrong.