-
Notifications
You must be signed in to change notification settings - Fork 5.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(std/hash): reimplement all hashes in WASM #6292
Conversation
Benchmark shows that WASM version is slower than native Rust but is faster than JS version. 10mb
100mb
|
I haven't dug into the PR in depth, but this is awesome! Not adding to the Deno binary, but providing hot path performance improvement. It also proves that WebAssembly doesn't perform better than Rust, so it isn't suitable for all hot paths, but it feels suitable for this one, as it is something that isn't part of the core of Deno, so it is a good mediation between all the options. |
Generally speaking, pure computation that doesn't trampoline between JS/WASM in a hot path should be very close native code once v8 has warmed up so these measurements look a little off at first glance. Based on the previous pull request, assuming these benchmarks are done the same way; the benchmarks seem to be including startup time? def run_benchmark(deno_exe, method, input_file):
# compile
subprocess.call([deno_exe, "run", "cli/tests/hash/hash.ts"])
for alg in algorithms:
args = [
deno_exe, "run", "--allow-read", "cli/tests/hash/hash.ts", method,
alg, input_file
]
start = time.time()
subprocess.call(args)
elapsed = time.time() - start
print "[{}] {}ms".format(alg, int(elapsed * 1000)) It would be more accurate if the measurement did not include the time it takes for a WebAssembly module to be decoded from base64, compiled to a module and instantiated as an instance. |
@caspervonb Thank you for the tips! New benchmark for pure computation actually shows that WASM version is pretty fast! 10mb
100mb
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@skdltmxn I agree with Kitson, this is awesome! Thanks for this work.
I would like to have the source code of how the wasm is generated in the tree - even tho we check-in the output. This will allow us to update and maintain it without depending on your repository. So could you please copy the files in https://github.com/skdltmxn/deno-hash over into std/hash/_wasm ?
@ry Sure. That's a good idea. Would it be okay to copy whole repo into std/hash/_wasm? |
@skdltmxn Yes, ideally removing as many files as possible and with a readme that gives the explicit commands to run in order to regenerate the wasm file |
#hash: DenoHash; | ||
#digested: boolean; | ||
|
||
constructor(algorithm: string) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be changed to: algorithm: SupportedAlgorithm
instead of algorithm: string
?
And you can remove as string
Lines 32 to 34 in b59bab3
export function createHash(algorithm: SupportedAlgorithm): Hasher { | |
return new Hash(algorithm as string); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In order to use SupportedAlgorithm
in hash.ts
, I have to import mod.ts
.
But mod.ts
is also importing hash.ts
, so I thought it would make cycle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In architectural point of view, I think Hash
class doesn't need to know about SupportedAlgorithm
since Hash
is just an wrapper for WASM which only uses string
.
SupportedAlgorithm
would do enough of its job for guarding algorithm for createHash
defined in mod.ts
.
@ry I have copied deno-hash repo into std/hash/_wasm. Please check README for build! |
std/hash/_wasm/build.ts
Outdated
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. | ||
|
||
import { encode as base64Encode } from "../../encoding/base64.ts"; | ||
import Terser from "https://cdn.pika.dev/terser@^4.7.0"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does terser do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see - it's a minifier. Is it possible to remove this dependency? Presumably minification doesn't help much?
In std we strive to not have any external dependencies: https://deno.land/manual/contributing/style_guide#minimize-dependencies-do-not-make-circular-imports
In this case, build.ts isn't part of std, it's just a script for generating the wasm, but I think it would be prudent for us to not rely on external code if possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also I'm getting an error when running this:
> deno run --allow-read --allow-write --allow-run ./build.ts
Download https://cdn.pika.dev/terser@^4.7.0
Download https://cdn.pika.dev/-/[email protected]/dist=es2019,mode=types/index.d.ts
Download https://cdn.pika.dev/-/[email protected]/dist=es2019/terser.js
Download https://cdn.pika.dev/-/[email protected]/dist=es2019,mode=types/tools/terser.d.ts
Download https://cdn.pika.dev/-/[email protected]/dist=es2019/source-map.js
Download https://cdn.pika.dev/-/[email protected]/dist=es2019,mode=types/tools/terser.d.ts
Download https://cdn.pika.dev/-/[email protected]/dist=es2019,mode=types/source-map.d.ts
Download https://cdn.pika.dev/-/[email protected]/dist=es2019,mode=types/index.d.ts
Compile file:https:///Users/rld/src/deno/std/hash/_wasm/build.ts
error: Uncaught SyntaxError: Invalid or unexpected token
at https://cdn.pika.dev/-/[email protected]/dist=es2019/terser.js:10:342617
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should make a huge difference if we are targeting wasm. Mostly it would be shortening variable names, the rest simply shouldn't matter in Web Assembly.
Adding minification support into Deno longer term is an objective, but we would want that to come from Rust.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will remove minifier :)
5975b66
to
784896b
Compare
@ry Removed Terser from WASM build script. I'm still not sure whether it is better to include WASM project into root Cargo.toml or not since we don't have to build WASM everytime and building WASM is done using deno itself. |
@skdltmxn I'm not sure either. Let's exclude it for now. We'll have to develop our own best practices for managing wasm in std - thanks for blazing a path : ) |
It seems there's probably a final step:
|
Oops, nope. It seems the build.ts does that. Sorry. However, I noticed in build.ts it uses an absolute URL: https://deno.land/[email protected]/encoding/base64.ts can you change this to be a relative URL? |
@ry All fixed! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM - thanks @skdltmxn !
I think we might have to continue iterating on this for a bit - but this is good enough for now
This PR is renewal of #6046.
WASM implementation is at https://github.com/skdltmxn/deno-hash