Re:Using WebAssembly to turn Rust crates into fast TypeScrip...
by chriscbr on Saturday July 01, 2023 @10:41PM
(#36557661)
Author here. Yeah, in fairness this post doesn't go into benchmarking (that would be interesting as a follow up). Though I would argue even for libraries that aren't numerically intensive (like the one I used in this blog post), I'd imagine the speeds are probably comparable to the JavaScript runtime if you don't have to boundary cross very often.
In this case, the main thing that was "fast" was that I didn't have to rewrite a nontrivial string formatting library in a new language (I literally couldn't find any other JavaScript libraries that had this kind of error-formatting functionality, so that would have been my only other option). :-)
Re:Using WebAssembly to turn Rust crates into fast TypeScrip...
by danenania on Saturday July 01, 2023 @11:15PM
(#36557884)
Cool post! I'm curious how big your wasm file ended up being?
For node, it would be interesting to compare performance, weight, and gotchas of the wasm approach vs. building a shared library with Rust and then pulling it in through node-gyp. Loading wasm is certainly a lot simpler, but multithreading support seems shaky and I imagine there may be some other drawbacks compared compiling into node directly, despite the added complexity.
Re:Using WebAssembly to turn Rust crates into fast TypeScrip...
by scottgpaulin on Saturday July 01, 2023 @10:12PM
(#36557498)
I guess it's best for stuff that isn't dom related
There are a few wasm libraries like finos/perspective and duckdb-wasm that are really useful in the client even though they don't interact with the dom
Re:Using WebAssembly to turn Rust crates into fast TypeScrip...
by throwme_123 on Saturday July 01, 2023 @11:04PM
(#36557815)
Thanks for the pointer to duckdb-wasm, didn't know about it!
> These micro benchmarks show that there is also no such thing as free lunch in the browser. We are paying for the increased processing efficiency in WebAssembly with a sightly less efficient evaluation on very small input. Our recommendation is therefore to use DuckDB-Wasm if you need SQL, the features or the raw speed on medium to large data sizes. Stick to existing frameworks if your dataset is very small or if your queries only contain simple scans and filters.
Re:Using WebAssembly to turn Rust crates into fast TypeScrip...
by foota on Saturday July 01, 2023 @10:45PM
(#36557684)
That's surprising to me, there was a Mozilla post a few years ago saying js to wasm allows 100 million calls per second for the slowest category, which seems speedy enough?
Re:Using WebAssembly to turn Rust crates into fast TypeScrip...
by chrisco255 on Saturday July 01, 2023 @10:56PM
(#36557755)
I think main issue is when it comes to DOM manipulation, the DOM is generally the bottleneck, not JavaScript. And since the DOM manipulations must be executed by JS anyways, you are often adding overhead by embedding your UI lib into wasm which then needs to message pass with JS to execute the DOM changes anyways.
Re:Using WebAssembly to turn Rust crates into fast TypeScrip...
by davidatbu on Sunday July 02, 2023 @02:09AM
(#36558728)
To me, the benchmarks you linked show that the fastest WASM web frameworks I know (leptos, dioxus, sycamore) are competitive with, or faster than, the JS frameworks most famously associated with speed, like SolidJS and Svelte; and that they are way faster than React.
That doesn't support your statement here, so I was wondering what takeaway you meant to direct our attention to when providing that link.
Re:Using WebAssembly to turn Rust crates into fast TypeScrip...
by chrisco255 on Sunday July 02, 2023 @04:59PM
(#36565678)
The most mature React-like library written in Rust, Yew, is slower than React, as the chart shows. Meanwhile the fastest frameworks are minimal JS / vanilla JS, including the fastest framework, mikado.
Either way it's clear that even a compile time language with no garbage collection can't get faster than the DOM itself allows, which is the crux of my point. In theory a compiled language should run at least twice as fast as JS, but it's not the case in the browser.
Re:Using WebAssembly to turn Rust crates into fast TypeScrip...
by davidatbu on Monday July 03, 2023 @04:26AM
(#36570265)
Dioxus is also a vDOM based framework (like React). Leptos is a fine-grained-reactivity framework (like SolidJS/Svelte).
They are both _way_ faster than React, and they are both faster than Vue and Svelte by a larger magnitude than SolidJS is faster than either of them.
That is not because Dioxus/leptos have less features than Yew. I'd actually argue they are more feature-full [1].
For icing on the cake: the most "bare-bones" WASM/Rust based entry to the benchmarks, "sledge-hammer", is as fast as the most bare-bones JS entry.
There are valid reasons for not using a Rust frontend framework (over-the-wire size, compilation speed, ecosystem, ..etc), but execution/DOM-manipulation speed is not one of them.
[1] I've used leptos, and tried out Yew, and have read through the docs of all three.
Re:Using WebAssembly to turn Rust crates into fast TypeScrip...
by foota on Sunday July 02, 2023 @03:47AM
(#36559265)
I'm confused, doesn't this show wasm bindgen performing near vanilla js? Admittedly, there's overhead, but fairly minimal. My assumption is that DOM operations are slow because of what they do under the hood, not because of the overhead of calling them.
Re:Using WebAssembly to turn Rust crates into fast TypeScrip...
by chrisco255 on Sunday July 02, 2023 @07:44PM
(#36567011)
It does show that, but vanilla JS is 20-30% faster on some of those benchmarks, and the fastest library in the test is a minimal JS lib. Either way, you would expect that a compiled, non-garbage collected, language should be able to achieve 50% or more improvement in speed over JS, but that's not the case in the browser, because the DOM is the bottleneck.
Re:Using WebAssembly to turn Rust crates into fast TypeScrip...
by davidatbu on Monday July 03, 2023 @04:42AM
(#36570366)
Like I said somewhere else "sledge-hammer" is _just as fast_ as Vanilla JS in those benchmarks (it's one of the "Vanilla Rust"/bare-bones entries to the benchmark).
Re:Using WebAssembly to turn Rust crates into fast TypeScrip...
by davidatbu on Monday July 03, 2023 @04:37AM
(#36570330)
Thanks for providing your data point!
If you're having another go, I'd recommend checking out sledge-hammer[0], a wasm-bindgen alternative that the folks behind Dioxus have been working on. It's a faster, but more limited version. Best of luck!
Re:Using WebAssembly to turn Rust crates into fast TypeScrip...
by sestep on Sunday July 02, 2023 @12:32AM
(#36558244)
Nice post! We're compiling Rust to Wasm for a numerical optimizer and got an order of magnitude speedup compared to our previous TypeScript implementation. It was tricky to get all the build pieces working together though.
Our team just uses wasm-bindgen though, and not wasm-pack; curious how much additional value you get from the latter? I could be mistaken but my impression is that wasm-pack uses Webpack; we've generally been trying to use esbuild instead (to make build times faster) but I haven't used wasm-pack beyond running the tutorial so maybe I don't know what I'm missing.
Re:Using WebAssembly to turn Rust crates into fast TypeScrip...
by andymac4182 on Sunday July 02, 2023 @05:07AM
(#36559712)
I have a need to create 1 library that can be reused in JVM, NodeJS/TS, Python, Go.
I remember reading something about doing something similar to this but it creates libraries for multiple languages. Have you done something similar before or do you have an idea where to look?
In our experience, the cost of boundary-crossing between wasm and js make it slower than js implementation for everything dom-related.
In this case, the main thing that was "fast" was that I didn't have to rewrite a nontrivial string formatting library in a new language (I literally couldn't find any other JavaScript libraries that had this kind of error-formatting functionality, so that would have been my only other option). :-)
For node, it would be interesting to compare performance, weight, and gotchas of the wasm approach vs. building a shared library with Rust and then pulling it in through node-gyp. Loading wasm is certainly a lot simpler, but multithreading support seems shaky and I imagine there may be some other drawbacks compared compiling into node directly, despite the added complexity.
There are a few wasm libraries like finos/perspective and duckdb-wasm that are really useful in the client even though they don't interact with the dom
> These micro benchmarks show that there is also no such thing as free lunch in the browser. We are paying for the increased processing efficiency in WebAssembly with a sightly less efficient evaluation on very small input. Our recommendation is therefore to use DuckDB-Wasm if you need SQL, the features or the raw speed on medium to large data sizes. Stick to existing frameworks if your dataset is very small or if your queries only contain simple scans and filters.
See: https://hacks.mozilla.org/2018/10/calls-between-javascript-a...
See: https://krausest.github.io/js-framework-benchmark/current.ht...
That doesn't support your statement here, so I was wondering what takeaway you meant to direct our attention to when providing that link.
Either way it's clear that even a compile time language with no garbage collection can't get faster than the DOM itself allows, which is the crux of my point. In theory a compiled language should run at least twice as fast as JS, but it's not the case in the browser.
They are both _way_ faster than React, and they are both faster than Vue and Svelte by a larger magnitude than SolidJS is faster than either of them.
That is not because Dioxus/leptos have less features than Yew. I'd actually argue they are more feature-full [1].
For icing on the cake: the most "bare-bones" WASM/Rust based entry to the benchmarks, "sledge-hammer", is as fast as the most bare-bones JS entry.
There are valid reasons for not using a Rust frontend framework (over-the-wire size, compilation speed, ecosystem, ..etc), but execution/DOM-manipulation speed is not one of them.
[1] I've used leptos, and tried out Yew, and have read through the docs of all three.
Leptos and Dioxus, Rust/WASM frameworks, are competitive with SolidJS, and right out destroy React, when it comes to manipulating the DOM!
So I'd love to hear, if possible, about when was it that you evaluated your WASM based solution, what language and framework you used, etc.
[0] https://krausest.github.io/js-framework-benchmark/2023/table...
This was last year though, maybe things got better now, so thanks for the pointers, will do another attempt!
If you're having another go, I'd recommend checking out sledge-hammer[0], a wasm-bindgen alternative that the folks behind Dioxus have been working on. It's a faster, but more limited version. Best of luck!
[0] https://github.com/Demonthos/sledgehammer_bindgen
Indeed, string decoding may have been our bottleneck as explained in [0].
Will definitely have a look.
PS: Evan from https://github.com/Demonthos, if you ever stumble upon this there is typo in the Dioxus link from your bio :)
Our team just uses wasm-bindgen though, and not wasm-pack; curious how much additional value you get from the latter? I could be mistaken but my impression is that wasm-pack uses Webpack; we've generally been trying to use esbuild instead (to make build times faster) but I haven't used wasm-pack beyond running the tutorial so maybe I don't know what I'm missing.
I remember reading something about doing something similar to this but it creates libraries for multiple languages. Have you done something similar before or do you have an idea where to look?