I'm curious why a lot of people get a 3x improvement. I get about 6.5-7x speed up, which suspiciously lines up with a 60hz vs 144hz framerate...
Comparing Rust and JavaScript
31–40 of 97 posts
Re: Comparing Rust and JavaScript
#32The innermost rendering loop in the JS seems to create and destruct an array instance for every single pixel iteration (see https://github.com/dmaynard/chaos-screen-saver/blob/master/s... ). I guess that this could be potentially optimized away by the JIT, but it will make things slower or at least less predictable.
Why do you think the JIT would be able to optimize this? And how would it go about it? I know only about a few rough things and heuristics. I wouldn't expect or assume that this would be optimized. It would probably have to recognize that the _usage_ of this function can be translated into a local mutation without allocating additional arrays. But from just looking at the function locally it isn't clear whether that…
Re: Comparing Rust and JavaScript
#33The difference in performance is about 3x and it looks like an pretty ideal case for wasm. Seems to match observations from Zaplip portmortem: > Rust is faster than JS in some cases, but those cases are rarer than we expected, and the performance gain is on the order of 2x some of the time, not 10x most of the time. https://zaplib.com/docs/blog_post_mortem.html
I'm really not so sure about this (see my comment further down[1]) but I'd love someone more knowledgeable to chime in.
Re: Comparing Rust and JavaScript
#34These comparisons are always highly biased by the kind of work being done. V8 is so good at optimizing code, it's usually possible to reach similar performance in JS. See https://surma.dev/things/js-to-asc/ Not that relevant, but it looks pretty terrible on a hi-dpi screen, it's probably not accounting for the pixel density when creating the canvas. Looks much better on a normal screen.
One thing I appreciate about say, Rust, vs C# is that in both using iterators to do operations on collections is the standard idiomatic thing to do. However in C# there is always some overhead, and at big scale you have to question whether that overhead is ok here. Usually is fine but sometimes you have to drop back to for loops.
With Rust the iterators pretty reliably get compiled down to very efficient code. So you just do the usual easy thing and get the good performance, no need to worry about it.
Re: Comparing Rust and JavaScript
#35Earlier quoted context omitted.
The fact that it was written in Rust (or any other non-VM lang) is meaningful because programs written in a Language that needs a VM (All the GC'd languages for example) need the vm to be shipped as well. Thus, making the WASM-program larger and slower.
Go is a GC language, but it doesn’t need a VM. It’s a native, statically linked binary that contains the Go runtime.
Re: Comparing Rust and JavaScript
#36The difference in performance is about 3x and it looks like an pretty ideal case for wasm. Seems to match observations from Zaplip portmortem: > Rust is faster than JS in some cases, but those cases are rarer than we expected, and the performance gain is on the order of 2x some of the time, not 10x most of the time. https://zaplib.com/docs/blog_post_mortem.html
Re: Comparing Rust and JavaScript
#37The innermost rendering loop in the JS seems to create and destruct an array instance for every single pixel iteration (see https://github.com/dmaynard/chaos-screen-saver/blob/master/s... ). I guess that this could be potentially optimized away by the JIT, but it will make things slower or at least less predictable.
Re: Comparing Rust and JavaScript
#38These comparisons are always highly biased by the kind of work being done. V8 is so good at optimizing code, it's usually possible to reach similar performance in JS. See https://surma.dev/things/js-to-asc/ Not that relevant, but it looks pretty terrible on a hi-dpi screen, it's probably not accounting for the pixel density when creating the canvas. Looks much better on a normal screen.
There can be value in "things will be fast by default" vs "things can be fast if you use a careful subset of the language". As well it is nice not to have to depend on v8 being the runtime to get good performance. One thing I appreciate about say, Rust, vs C# is that in both using iterators to do operations on collections is the standard idiomatic thing to do. However in C# there is always some overhead, and at big s…
One could equally say that there's value in "things will be general by default" vs "things can be general if you use obscure features of a language and thirty libraries to generalize the things that aren't general yet".
Yet most programs seem to be following the 80/20 rule, so the majority of code that has been ever written seems to prefer generality over raw speed. Of course one possible solution is to write the general parts and the fast parts of your program in different languages, but interoperation may be tedious.
Re: Comparing Rust and JavaScript
#39I wish there was an "about" blurb. Perhaps 2-6 paragraphs explaining what's going on? Although it's obvious that you're comparing JavaScript and WASM performance, the devil is in the details. What exactly are you comparing? There's quite a bit of overhead in calling out from WASM to the DOM; how are you making WASM faster? How much "JavaScript" is involved in the WASM version? Are you manipulating a Canvas? Generatin…
If you check out the code, you will notice that wasm isn't talking to the DOM. Its purpose is to generate the image data as a Uint8Array, which is then passed to the canvas [0], same way the javascript implementation does it
[0] - https://github.com/dmaynard/chaos-screen-saver/blob/93187f84...
Re: Comparing Rust and JavaScript
#40The innermost rendering loop in the JS seems to create and destruct an array instance for every single pixel iteration (see https://github.com/dmaynard/chaos-screen-saver/blob/master/s... ). I guess that this could be potentially optimized away by the JIT, but it will make things slower or at least less predictable.
A quick profiling seemed to indicate that just a bit less than 10% of the JS time is being spent on the DOM rather than the calculations at hand. I wonder how much of that could be reclaimed simply by running the calculation in a web worker.
I suspect the bitwise AND operator every loop is another big performance issue. Normally, the JIT would leave the loop iterator as a 31-bit int, but because it is stored in a shared object, I suspect it must (f64 -> i31 -> AND -> f64) every time. A local variable that updates the object variable every 64ms and resets to zero would probably be faster.
The decPixel function should use a switch statement with values of 0, 1, 255, and default so it only needs to branch one time. This is probably a decent performance win too as around 15-20% of all time is spent here.
EDIT: I should praise the author for using a ternary instead of Math.max() as very few people know that the ternary is literally 100x faster. I wonder why this optimization was never made as it seems common enough.