I should mention that I initially started writing this thread looking for help getting a working rewrite, then accidentally managed to get it working while trying to document the issue. I'm kind of learning both javascript and rust while using them in a project. here is the original, and here is my fork
I'm trying to decide whether to use neon or wasm and decided to check out a performance comparison, both in terms of speed and the underlying code complexity.
I cloned and ran the original repo that was comparing short and long ops/sec in native js, a neon based rust project and a wasm based rust project. the results were similar to the posted benchmark:
wasm#short x 77,917 ops/sec ±0.57% (82 runs sampled)
wasm#long x 34,726 ops/sec ±1.20% (82 runs sampled)
js#short x 275,189 ops/sec ±0.69% (92 runs sampled)
js#long x 21,498 ops/sec ±0.75% (89 runs sampled)
neon#short x 644,123 ops/sec ±0.34% (92 runs sampled)
neon#long x 182,730 ops/sec ±0.32% (91 runs sampled)
the wasm test results were much slower than I expected so I started comparing the implementation between the original neon and wasm implementations.
the wasm implementation seemed far more complex than the neon rust implementation,and had more of the work done by native javascript. From what I was reading it seems that wasm previously didn't support string operations directly, which seems to no longer be the case, and the neon implementation seemed closer to the type of examples listed in the rust wasm docs, so I've been trying to rewrite the wasm implementation. I made a lot of small changes to various non rust files and if you need me to list all of them I can.
the test that called all 3 implementations seemed to be passing strings directly, so I changed the argument type to &string
and the return type orignally to Result<String,JsValue>
. currently the function is this:
#[wasm_bindgen]
pub fn digest(string: &str) -> Option<String> {
let mut m = Sha1::new();
m.update(string.as_bytes());
let dgst= m.digest().to_string();
Some(dgst)
}
built in the Makefile via:
cd wasm && wasm-pack build --release --target nodejs
I didn't change the actual test other than removing the ready.then
block that wasn't necessary anymore.
the new results are this:
wasm#short x 229,630 ops/sec ±0.47% (85 runs sampled)
wasm#long x 114,446 ops/sec ±0.49% (89 runs sampled)
js#short x 275,967 ops/sec ±0.70% (90 runs sampled)
js#long x 20,944 ops/sec ±0.63% (89 runs sampled)
neon#short x 691,628 ops/sec ±0.35% (94 runs sampled)
neon#long x 188,252 ops/sec ±0.39% (91 runs sampled)
while this is definitely a major improvement, npm is spitting out a lot of complaints prior to starting the tests about unhandled promise rejections, and I want to make sure this isn't effecting the actual runtime, plus I want to make sure that there is nothing in my wasm rewrite that would cause issues if someone actually tried to use the implementation as is. While I doubt anyone will, I'm doing this to try to figure out the both the fastest and the least complicated way of getting both languages to interact(the two may or may not be mutually exclusive), and unintended problems at runtime definitely qualifies as complicated.