diff --git a/n-body/README.md b/n-body/README.md index f3d370b..897cede 100644 --- a/n-body/README.md +++ b/n-body/README.md @@ -28,26 +28,27 @@ to start a local server. To run the benchmark: -``` +```bash $> npm test [steps=1000000] ``` Benchmark + ========= ***Environment:*** + - MacBook Pro (15-inch, 2019) -- macOS 10.15.3 -- node.js v13.8.0 +- macOS 12.4.0 +- node.js v18.4.0 - rustc 1.42.0-nightly (3a3f4a7cb 2019-12-28) ***Results:*** | Target | Time, ***ms*** | Size, ***KB*** | |-------------------------|-----------------|----------------| -| **AssemblyScript WASM** | **1602** | **1.6** | -| AssemblyScript ASMJS | 2368 | 10* | -| JavaScript | 1616 | 5* | -| Rust WASM | 1618 | 2 | +| **AssemblyScript WASM** | **1599** | **1.8** | +| JavaScript | 11608 | 5* | +| Rust WASM | 1631 | 2 | ___* unminified___ diff --git a/n-body/asconfig.json b/n-body/asconfig.json new file mode 100644 index 0000000..89e7879 --- /dev/null +++ b/n-body/asconfig.json @@ -0,0 +1,17 @@ +{ + "options": { + "runtime": "stub", + "importMemory": true, + "sourceMap": true + }, + "targets": { + "wasm": { + "outFile": "build/as_nbody.wasm", + "textFile": "build/as_nbody.wat", + "optimizeLevel": 3, + "shrinkLevel": 0, + "converge": true, + "noAssert": true + } + } +} diff --git a/n-body/build/as_nbody.wasm b/n-body/build/as_nbody.wasm index ed27e75..ab5b461 100644 Binary files a/n-body/build/as_nbody.wasm and b/n-body/build/as_nbody.wasm differ diff --git a/n-body/package.json b/n-body/package.json index 1fb86a8..5b87d05 100644 --- a/n-body/package.json +++ b/n-body/package.json @@ -4,10 +4,9 @@ "license": "Apache-2.0", "private": true, "scripts": { - "asbuild:wasm": "asc assembly/index.ts -b build/as_nbody.wasm -t build/as_nbody.wat -O3 --runtime stub --noAssert --importMemory", - "asbuild:js": "asc assembly/index.ts -j build/as_nbody.js -O3 --runtime stub --noAssert && node scripts/postprocess-js", - "asbuild": "npm run asbuild:wasm && npm run asbuild:js", - "tsbuild": "tsc -p assembly -t ES2017 -m commonjs --outDir build", + "asbuild:wasm": "asc assembly/index.ts --target wasm", + "asbuild": "npm run asbuild:wasm", + "tsbuild": "tsc -p assembly -t esnext -m commonjs --outDir build && node scripts/postprocess", "rsbuild": "cd rust && RUSTFLAGS='-C link-arg=-s' cargo +nightly build --release", "build": "npm run asbuild && npm run tsbuild && npm run rsbuild", "start": "npx serve", @@ -15,6 +14,6 @@ }, "devDependencies": { "assemblyscript": "latest", - "typescript": "^3.9.7" + "typescript": "^4.7.4" } } diff --git a/n-body/scripts/postprocess-js.js b/n-body/scripts/postprocess-js.js deleted file mode 100644 index 9801c05..0000000 --- a/n-body/scripts/postprocess-js.js +++ /dev/null @@ -1,8 +0,0 @@ -const fs = require("fs"); -const path = require("path"); - -const filename = path.join(__dirname, "..", "build" , "as_nbody.js"); -var source = fs.readFileSync(filename, { encoding: "utf8" }); -source = source.replace(/^export var ([^ ]+) =/mg, ($0, $1) => "exports." + $1 + " = "); -source = source.replace("import { abort } from 'env';", "function abort() { throw new Error('abort'); }"); -fs.writeFileSync(filename, source); diff --git a/n-body/scripts/postprocess.js b/n-body/scripts/postprocess.js new file mode 100644 index 0000000..8ad9f43 --- /dev/null +++ b/n-body/scripts/postprocess.js @@ -0,0 +1,13 @@ +const fs = require("fs"); +const path = require("path"); + +const filename = path.join(__dirname, "..", "build" , "index.js"); +const source = fs.readFileSync(filename, { encoding: "utf8" }); + +function removeUnchecked(str) { + return str + .replace(/unchecked\((.*?)\)/g, (_, _1) => _1) + .replace(/unchecked\((.*?)\)/g, (_, _1) => _1); +} + +fs.writeFileSync(filename, removeUnchecked(source)); diff --git a/n-body/tests/index.js b/n-body/tests/index.js index 156a598..ef8f154 100644 --- a/n-body/tests/index.js +++ b/n-body/tests/index.js @@ -1,41 +1,13 @@ const fs = require("fs"); -// Load WASM version +// Load AssemblyScript version const nbodyAS = require("../assembly/index.js"); -var nbodyRS; -try { - nbodyRS = require("../rust/index.js"); -} catch (e) {} +// Load Rust/wasm version +let nbodyRS; +try { nbodyRS = require("../rust/index.js"); } catch (e) {} // Load JS version -var src = fs.readFileSync(__dirname + "/../build/as_nbody.js", "utf8") - .replace(/const retasmFunc[^$]*$/g, ""); - -const nbodyAS_JS = eval(src + ";asmFunc")({ - Int8Array, - Int16Array, - Int32Array, - Uint8Array, - Uint16Array, - Uint32Array, - Float32Array, - Float64Array, - Math -}, { - abort: () => { throw Error(); } -}, new ArrayBuffer(0x10000)); - -// Load JS version -src = fs.readFileSync(__dirname + "/../build/index.js", "utf8"); -const scopeJS = { - require: () => {}, - exports: {}, - unchecked: expr => expr -}; - -const nbodyJS = new Function( - ...Object.keys(scopeJS).concat(src + "\nreturn exports"))(...Object.values(scopeJS) -); +const nbodyJS = require("../build/index.js"); function gcCollect() { if (global.gc) { @@ -58,45 +30,29 @@ function test(nbody, steps) { return t; } -var steps = process.argv.length > 2 ? parseInt(process.argv[2], 10) : 20000000; - -function prologue(name, steps) { - console.log("Performing " + steps + " steps (" + name + ") ..."); -} +const steps = process.argv.length > 2 + ? parseInt(process.argv[2], 10) + : 20000000; -function epilogue(time) { - console.log("Took " + (time[0] * 1e3 + time[1] / 1e6) + "ms"); +function bench(name, fn) { + console.log(`Performing ${steps} steps (${name}) ...`); + const time = test(fn, steps); + console.log(`Took ${(time[0] * 1e3 + time[1] / 1e6).toFixed(0)} ms`); } console.log("\nCOLD SERIES:\n"); -prologue("AssemblyScript WASM", steps); -epilogue(test(nbodyAS, steps)); - -prologue("AssemblyScript JS", steps); -epilogue(test(nbodyAS_JS, steps)); - -prologue("JS", steps); -epilogue(test(nbodyJS, steps)); - +bench("AssemblyScript WASM", nbodyAS); +bench("JS", nbodyJS); if (nbodyRS) { - prologue("Rust WASM", steps); - epilogue(test(nbodyRS, steps)); + bench("Rust WASM", nbodyRS); } console.log("\nWARMED UP SERIES:\n"); sleep(1000); -prologue("AssemblyScript WASM", steps); -epilogue(test(nbodyAS, steps)); - -prologue("AssemblyScript JS", steps); -epilogue(test(nbodyAS_JS, steps)); - -prologue("JS", steps); -epilogue(test(nbodyJS, steps)); - +bench("AssemblyScript WASM", nbodyAS); +bench("JS", nbodyJS); if (nbodyRS) { - prologue("Rust WASM", steps); - epilogue(test(nbodyRS, steps)); + bench("Rust WASM", nbodyRS); }