Closed StephenLynx closed 3 years ago
Take care, there is a bug in your code. You should run the benchmarks one after another (await runOld(); await run()
). Otherwise WASM execution might block the JS main thread and the native version will only get back the control after hash-wasm is finished. That's why you see inconsistent behavior.
You are comparing the native SubtleCrypto API with WASM. WASM libraries will probably never outperform the native implementations, because they need to be compiled at runtime and they doesn't have access to all specialized CPU instructions. So native implementations will be always faster, but they also have disadvantages (various levels of browser support, https requirement, complicated build processes, less forward-compatibility, etc.). For PBKDF2-SHA512 you might want to use SubtleCrypto if available and use hash-wasm
as a fallback implementation where SubtleCrypto is not working.
Yeah, I was aware of how they might run concurrently. But even when I ran wasm on it's own, it was quite slow. My issue here is that subtle doesn't let you run concurrently, even if you run it multiple times across different web workers, they will run sequentially, hence why I'm looking into wasm alternatives. I know it can't compare, but when it takes over 3 seconds and native takes 9 milliseconds, the gap is just way too large, I thought there was something wrong here. Are you SURE this is as good as it gets with WASM? There is nothing wrong with my code or with the library?
Please note that having the DevTools open slows down the interpreter (certain optimizations are disabled).
On my computer I get the following measurements: Chrome SubtleCrypto + DevTools: 36ms Chrome hash-wasm + DevTools: 971ms (27x slower) Chrome SubtleCrypto: 35ms Chrome hash-wasm: 203ms (6x slower)
Firefox SubtleCrypto + DevTools: 93ms Firefox hash-wasm + DevTools: 1031ms (11x slower) Firefox SubtleCrypto: 94ms Firefox hash-wasm: 335ms (3.5x slower)
Also hash-wasm is not fully optimized for PBKDF2, because I wanted to keep the flexibility of supplying any hash algorithm without increasing the bundle size too much. But still, I believe that 3-6x slowdown is something acceptable when comparing to native implementations. WASM is still relatively young. We will probably see better figures in the future.
One more thing I noticed: Firefox seems to cheat... It's caching the SubtleCrypto results between runs and even between page refreshes. When I randomize the password, the 1ms timings disappear and I get a consistent 95 ms.
I tried not using the console, I tried disabling devtools on about:config using 2 settings and I never got a time better than 1.9s.
What architecture do you use? I tested with Windows 10 Chrome v91 x64 Intel i7-7700k. I didn't change anything in about:config... I just refresh the page with dev tools closed and after some seconds I open it to see the results. Could you try running it in Node.js?
i5-3337U @ 1.80GHz, centos 7, firefox 78.11.0esr 64 bits. On node I can just use node's pbkdf2 implementation, I only have a use for it on the browser.
Seeing the node.js results would be useful because it behaves similarly to Chrome when DevTools is closed. In that way we could exclude the Chrome issues.
Yeah, I can see what you mean. Chromium with the console closed managed to run on 0.7s, console open, over 4 seconds. So it points to something funny going on firefox.
I think this issue can be closed.
Can it? Did you manage to figure anything on firefox that could be causing it? Or are you just assuming there's nothing to be done on your side?
For me the performance looks already good in Firefox: https://github.com/Daninet/hash-wasm/issues/21#issuecomment-866311497 I cannot reproduce those Firefox performance issues you mentioned. But tell me if you have a clue how can I do that.
Generally speaking, when I'm doing optimizations, I only check the raw WASM instructions of the different hash algorithms and try to make them the most efficiently executable on modern CPUs. It's the browser's job to do generate efficient native assembly from it.
I don't want to make any browser- or platform-specific optimizations. It would be a never ending job to keep track of what instructions are efficient on each platform / browser engine version and it would also make the bundles a lot larger if I start having N builds for the different environments.
I've just seen that you mentioned that you're using firefox 78.11.0esr. That's a pretty old version. Could you try with the latest v89.0.2?
If you are not having issues on a newer version then I suppose they already changed whatever was causing. I'm using that version because is what centos 7 ships.
This is my code: