Clean up benchmarks

This commit is contained in:
Remko Tronçon 2018-05-29 21:14:22 +02:00
parent 4043db2afd
commit ee0eeb85ef
13 changed files with 306 additions and 85 deletions

1
.eslintignore Normal file
View file

@ -0,0 +1 @@
dist

View file

@ -6,7 +6,7 @@ endif
WEBPACK=npx webpack
WEBPACK_DEV_SERVER=npx webpack-dev-server
WASM_FILES=src/waforth.wasm tests/benchmarks/sieve-vanilla/sieve-vanilla.wasm
WASM_FILES=src/waforth.wasm tests/benchmarks/sieve-vanilla.wasm
all: $(WASM_FILES)
$(WEBPACK) --mode=production
@ -20,7 +20,7 @@ src/waforth.wasm: src/waforth.wat dist
racket -f $< > src/waforth.wat.tmp
$(WAT2WASM) $(WAT2WASM_FLAGS) -o $@ src/waforth.wat.tmp
tests/benchmarks/sieve-vanilla/sieve-vanilla.wasm: tests/benchmarks/sieve-vanilla/sieve-vanilla.wat
tests/benchmarks/sieve-vanilla.wasm: tests/benchmarks/sieve-vanilla.wat
$(WAT2WASM) $(WAT2WASM_FLAGS) -o $@ $<
dist:

View file

@ -1,18 +1,22 @@
{
"private": true,
"dependencies": {
"immutability-helper": "^2.7.0",
"jq-console": "^2.13.2",
"jquery": "^3.3.1",
"preact": "^8.2.9",
"promise-polyfill": "^7.1.2"
},
"devDependencies": {
"babel-core": "^6.26.3",
"babel-loader": "^7.1.4",
"babel-plugin-transform-react-jsx": "^6.24.1",
"babel-preset-env": "^1.7.0",
"bin-loader": "^0.1.0",
"chai": "^4.1.2",
"css-loader": "^0.28.11",
"eslint": "4.13.1",
"eslint-plugin-react": "^7.8.2",
"html-webpack-plugin": "^3.2.0",
"mocha": "^5.2.0",
"style-loader": "^0.21.0",

View file

@ -0,0 +1,5 @@
extends:
- plugin:react/recommended
rules:
react/react-in-jsx-scope: 0
no-unused-vars: [2, { "varsIgnorePattern": "^h$" }]

View file

@ -0,0 +1,16 @@
table {
text-align: center;
border-collapse: collapse;
}
table thead th {
min-width: 4em;
border-bottom: thin solid grey;
}
pre.output {
margin: 0;
font-size: .5em;
text-align: left;
}

161
tests/benchmarks/index.js Normal file
View file

@ -0,0 +1,161 @@
import WAForth from "../../src/shell/WAForth";
import sieve from "../../src/shell/sieve";
import sieveVanillaModule from "./sieve-vanilla.wasm";
import { Component, render, h } from "preact";
import update from "immutability-helper";
import "./index.css";
////////////////////////////////////////////////////////////////////////////////
// Initial setup
////////////////////////////////////////////////////////////////////////////////
const setup = [];
const forth = new WAForth();
let outputBuffer = [];
forth.onEmit = c => {
outputBuffer.push(String.fromCharCode(c));
};
setup.push(
forth.start().then(() => {
forth.run(sieve);
})
);
let sieveVanilla;
setup.push(
WebAssembly.instantiate(sieveVanillaModule, {
js: {
print: x => console.log(x)
}
}).then(instance => {
sieveVanilla = instance.instance.exports.sieve;
})
);
////////////////////////////////////////////////////////////////////////////////
const ITERATIONS = 5;
const LIMIT = 50000000;
const benchmarks = [
{
name: "sieve",
fn: () => {
outputBuffer = [];
forth.run(`${LIMIT} sieve`);
return outputBuffer.join("");
}
},
{
name: "sieve-vanilla",
fn: () => {
return sieveVanilla(LIMIT);
}
}
];
////////////////////////////////////////////////////////////////////////////////
const iterations = Array.from(Array(ITERATIONS).keys());
class Benchmarks extends Component {
constructor(props) {
super(props);
const results = {};
benchmarks.forEach(({ name }) => (results[name] = []));
this.state = {
initialized: false,
done: false,
results
};
}
componentDidMount() {
Promise.all(setup).then(() => {
this.setState({ initialized: true });
let benchmarkIndex = 0;
let benchmarkIteration = 0;
const runNext = () => {
const t1 = performance.now();
const output = benchmarks[benchmarkIndex].fn();
const t2 = performance.now();
this.setState({
results: update(this.state.results, {
[benchmarks[benchmarkIndex].name]: {
[benchmarkIteration]: {
$set: { time: (t2 - t1) / 1000.0, output }
}
}
})
});
if (benchmarkIteration < ITERATIONS - 1) {
benchmarkIteration += 1;
window.setTimeout(runNext, 500);
} else if (benchmarkIndex < benchmarks.length - 1) {
benchmarkIndex += 1;
benchmarkIteration = 0;
window.setTimeout(runNext, 500);
} else {
this.setState({ done: true });
}
};
window.setTimeout(runNext, 500);
});
}
render() {
const { initialized, results } = this.state;
if (!initialized) {
return <div>Loading</div>;
}
return (
<div>
<table>
<thead>
<tr>
<th />
{iterations.map(i => <th key={i}>{i}</th>)}
<th>Avg</th>
</tr>
</thead>
<tbody>
{benchmarks.map(({ name }) => {
const benchmark = results[name];
const sum = benchmark.reduce((acc, { time }) => acc + time, 0);
return [
<tr key={`${name}-time`}>
<th>{name}</th>
{iterations.map(i => (
<td key={i}>
{benchmark[i] == null ? null : (
<span>{benchmark[i].time.toFixed(2)}s</span>
)}
</td>
))}
<th>
{benchmark.length === ITERATIONS ? (
<span>{(sum / benchmark.length).toFixed(2)}s</span>
) : (
"⌛"
)}
</th>
</tr>,
<tr key={`${name}-output`}>
<th />
{iterations.map(i => (
<td key={i}>
<pre className="output">
{benchmark[i] == null ? null : benchmark[i].output}
</pre>
</td>
))}
</tr>
];
})}
</tbody>
</table>
</div>
);
}
}
render(<Benchmarks />, document.body);

View file

@ -1,10 +0,0 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Sieve (Vanilla)</title>
</head>
<body>
<script src="./index.js"></script>
</body>
</html>

View file

@ -1,12 +0,0 @@
fetch("sieve-vanilla.wasm")
.then(resp => resp.arrayBuffer())
.then(module =>
WebAssembly.instantiate(module, {
js: {
print: x => console.log(x)
}
})
)
.then(instance => {
window.sieve = instance.instance.exports.sieve;
});

View file

@ -1,10 +0,0 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script src="./index.js"></script>
</body>
</html>

View file

@ -1,42 +0,0 @@
import WAForth from "../../../src/shell/WAForth";
import sieve from "../../../src/shell/sieve";
const ITERATIONS = 3;
const LIMIT = 50000000;
const forth = new WAForth();
let outputBuffer = [];
forth.onEmit = c => {
outputBuffer.push(String.fromCharCode(c));
};
document.body.innerHTML = "Loading...";
forth.start().then(
() => {
document.body.innerHTML = "<div>Running...</div>";
forth.run(sieve);
let i = 0;
const run = () => {
if (i < ITERATIONS) {
outputBuffer = [];
const t1 = performance.now();
outputBuffer = [77, 88];
forth.run(`${LIMIT} sieve`);
const t2 = performance.now();
document.body.innerHTML =
document.body.innerHTML +
`<div><pre style='display: inline-block; margin: 0; margin-right: 1rem'>${outputBuffer.join(
""
)}</pre><span>${(t2 - t1) / 1000.0}</span></div>`;
i += 1;
window.setTimeout(run, 0);
} else {
document.body.innerHTML = document.body.innerHTML + "<div>Done</div>";
}
};
window.setTimeout(run, 10);
},
err => {
console.error(err);
document.body.innerHTML = "Error";
}
);

View file

@ -22,7 +22,8 @@ function config({ entry, outputDir, title, template, mode }) {
use: {
loader: "babel-loader",
options: {
presets: ["es2015"]
presets: ["es2015"],
plugins: [["transform-react-jsx", { pragma: "h" }]]
}
}
},
@ -80,9 +81,9 @@ module.exports = (env, argv) => [
mode: argv.mode
}),
config({
title: "Sieve Benchmark",
entry: "./tests/benchmarks/sieve/index.js",
outputDir: "sieve",
title: "Benchmarks",
entry: "./tests/benchmarks/index.js",
outputDir: "benchmarks",
mode: argv.mode
})
];

117
yarn.lock
View file

@ -332,6 +332,10 @@ arrify@^1.0.0, arrify@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
asap@~2.0.3:
version "2.0.6"
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
asn1.js@^4.0.0:
version "4.10.1"
resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0"
@ -452,6 +456,14 @@ babel-helper-builder-binary-assignment-operator-visitor@^6.24.1:
babel-runtime "^6.22.0"
babel-types "^6.24.1"
babel-helper-builder-react-jsx@^6.24.1:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz#39ff8313b75c8b65dceff1f31d383e0ff2a408a0"
dependencies:
babel-runtime "^6.26.0"
babel-types "^6.26.0"
esutils "^2.0.2"
babel-helper-call-delegate@^6.24.1:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d"
@ -610,6 +622,10 @@ babel-plugin-syntax-flow@^6.18.0:
version "6.18.0"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d"
babel-plugin-syntax-jsx@^6.8.0:
version "6.18.0"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946"
babel-plugin-syntax-object-rest-spread@^6.8.0:
version "6.13.0"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5"
@ -858,6 +874,14 @@ babel-plugin-transform-object-rest-spread@^6.22.0:
babel-plugin-syntax-object-rest-spread "^6.8.0"
babel-runtime "^6.26.0"
babel-plugin-transform-react-jsx@^6.24.1:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz#840a028e7df460dfc3a2d29f0c0d91f6376e66a3"
dependencies:
babel-helper-builder-react-jsx "^6.24.1"
babel-plugin-syntax-jsx "^6.8.0"
babel-runtime "^6.22.0"
babel-plugin-transform-regenerator@^6.22.0, babel-plugin-transform-regenerator@^6.24.1:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f"
@ -1680,6 +1704,10 @@ copy-descriptor@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
core-js@^1.0.0:
version "1.2.7"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
core-js@^2.4.0, core-js@^2.5.0:
version "2.5.6"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.6.tgz#0fe6d45bf3cac3ac364a9d72de7576f4eb221b9d"
@ -2163,6 +2191,12 @@ encodeurl@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
encoding@^0.1.11:
version "0.1.12"
resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb"
dependencies:
iconv-lite "~0.4.13"
end-of-stream@^1.0.0, end-of-stream@^1.1.0:
version "1.4.1"
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43"
@ -2253,6 +2287,15 @@ escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
eslint-plugin-react@^7.8.2:
version "7.8.2"
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.8.2.tgz#e95c9c47fece55d2303d1a67c9d01b930b88a51d"
dependencies:
doctrine "^2.0.2"
has "^1.0.1"
jsx-ast-utils "^2.0.1"
prop-types "^15.6.0"
eslint-scope@^3.7.1:
version "3.7.1"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8"
@ -2526,6 +2569,18 @@ faye-websocket@~0.11.0:
dependencies:
websocket-driver ">=0.5.1"
fbjs@^0.8.16:
version "0.8.16"
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db"
dependencies:
core-js "^1.0.0"
isomorphic-fetch "^2.1.1"
loose-envify "^1.0.0"
object-assign "^4.1.0"
promise "^7.1.1"
setimmediate "^1.0.5"
ua-parser-js "^0.7.9"
figures@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e"
@ -3130,7 +3185,7 @@ iconv-lite@0.4.19:
version "0.4.19"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
iconv-lite@^0.4.17, iconv-lite@^0.4.4:
iconv-lite@^0.4.17, iconv-lite@^0.4.4, iconv-lite@~0.4.13:
version "0.4.23"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63"
dependencies:
@ -3164,6 +3219,12 @@ ignore@^3.3.3, ignore@^3.3.5:
version "3.3.8"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.8.tgz#3f8e9c35d38708a3a7e0e9abb6c73e7ee7707b2b"
immutability-helper@^2.7.0:
version "2.7.0"
resolved "https://registry.yarnpkg.com/immutability-helper/-/immutability-helper-2.7.0.tgz#4ea9916cc8f45142ec3e3f0fce75fa5d66fa1b38"
dependencies:
invariant "^2.2.0"
import-local@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc"
@ -3266,7 +3327,7 @@ into-stream@^3.1.0:
from2 "^2.1.1"
p-is-promise "^1.1.0"
invariant@^2.2.2:
invariant@^2.2.0, invariant@^2.2.2:
version "2.2.4"
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
dependencies:
@ -3508,7 +3569,7 @@ is-scoped@^1.0.0:
dependencies:
scoped-regex "^1.0.0"
is-stream@^1.0.0, is-stream@^1.1.0:
is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
@ -3560,6 +3621,13 @@ isobject@^3.0.0, isobject@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
isomorphic-fetch@^2.1.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9"
dependencies:
node-fetch "^1.0.1"
whatwg-fetch ">=0.10.0"
istextorbinary@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/istextorbinary/-/istextorbinary-2.2.1.tgz#a5231a08ef6dd22b268d0895084cf8d58b5bec53"
@ -3677,6 +3745,12 @@ json5@^0.5.0, json5@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
jsx-ast-utils@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz#e801b1b39985e20fffc87b40e3748080e2dcac7f"
dependencies:
array-includes "^3.0.3"
keyv@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.0.0.tgz#44923ba39e68b12a7cec7df6c3268c031f2ef373"
@ -3868,7 +3942,7 @@ long@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b"
loose-envify@^1.0.0:
loose-envify@^1.0.0, loose-envify@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
dependencies:
@ -4257,6 +4331,13 @@ node-dir@0.1.8:
version "0.1.8"
resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.8.tgz#55fb8deb699070707fb67f91a460f0448294c77d"
node-fetch@^1.0.1:
version "1.7.3"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
dependencies:
encoding "^0.1.11"
is-stream "^1.0.1"
node-forge@0.7.5:
version "0.7.5"
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df"
@ -5009,6 +5090,10 @@ postcss@^6.0.1:
source-map "^0.6.1"
supports-color "^5.4.0"
preact@^8.2.9:
version "8.2.9"
resolved "https://registry.yarnpkg.com/preact/-/preact-8.2.9.tgz#813ba9dd45e5d97c5ea0d6c86d375b3be711cc40"
prelude-ls@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
@ -5064,6 +5149,20 @@ promise-polyfill@^7.1.2:
version "7.1.2"
resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-7.1.2.tgz#ab05301d8c28536301622d69227632269a70ca3b"
promise@^7.1.1:
version "7.3.1"
resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
dependencies:
asap "~2.0.3"
prop-types@^15.6.0:
version "15.6.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.1.tgz#36644453564255ddda391191fb3a125cbdf654ca"
dependencies:
fbjs "^0.8.16"
loose-envify "^1.3.1"
object-assign "^4.1.1"
proxy-addr@~2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.3.tgz#355f262505a621646b3130a728eb647e22055341"
@ -5643,7 +5742,7 @@ set-value@^2.0.0:
is-plain-object "^2.0.3"
split-string "^3.0.1"
setimmediate@^1.0.4:
setimmediate@^1.0.4, setimmediate@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
@ -6162,6 +6261,10 @@ typedarray@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
ua-parser-js@^0.7.9:
version "0.7.18"
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.18.tgz#a7bfd92f56edfb117083b69e31d2aa8882d4b1ed"
uglify-es@^3.3.4:
version "3.3.9"
resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677"
@ -6535,6 +6638,10 @@ websocket-extensions@>=0.1.1:
version "0.1.3"
resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29"
whatwg-fetch@>=0.10.0:
version "2.0.4"
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f"
whet.extend@~0.9.9:
version "0.9.9"
resolved "https://registry.yarnpkg.com/whet.extend/-/whet.extend-0.9.9.tgz#f877d5bf648c97e5aa542fadc16d6a259b9c11a1"