> Now that you know how you can easily create and use WebAssembly code, there is nothing stopping you from refactoring performance critical parts of your code using WASM.
There is, writing WASM by hand will not only create an unmanageable mess but also should be strongly discouraged, WASM is supposed to be a target not a “language” like the author is mentioning.
Also, it’s doubtful WASM is actually faster than plain JavaScript for most use cases when not speaking of benchmark-optimized tests. It’s not the point of WASM.
Unfortunately, the way I see it is the ASM part in WASM is going to create a disaster where people really believe it’s an analog to physical machine code.
Even speaking of proper assembly code, it’s not advisable to write it by hand except in very rare and specific scenarios such as cryptography as it’s most of the time going to be slower than using an optimizing compiler anyway.
Though it might be useful in niche situations. In the C world, crypto libraries often use inline assembler. I assume there might be similar use cases for JS and WASM.
Not really applicable here as WASM is not machine code and is interpreted / compiled / JIT compiled behind the scenes. Something you definitely don’t want for cryptography.
I wasn't directly suggesting cryptography. Rather pointing to a similar "niche" use case of inlining in a different ecosystem.
I assume there are several use cases where WASM is faster than JavaScript, despite all the things you mention. Some types of canvas manipulation are typically faster with WASM, for example.
WASM was explicitly designed to be human readable and human editable. The WAT format wouldn't have been created if that wasn't the intention[0]. That's a lot of effort being invested into readability, and it would have been a lot simpler to just create the binary format and not worry about syntax or WAT compilers if humans weren't meant to be able to read and debug the final product.
Of course I wouldn't write web assembly by hand normally for most projects, but I also wouldn't create a blanket rule that it should be discouraged across the board. It's another language that goes through a compile process, just a very specialized one, like assembly.
I thought that one of the major points of WASM was that it would be fast? The first advantage listed on the official WebAssembly website is "Efficient and fast" [0]. But I suppose you wrote "the point" - it's just one of several points. But ideally, it should run at "native speed", right?
It is designed to be able to skip the "tier up JIT" stage that JS code has to go through, where JS code is profiled at runtime to decide what should be optimized, what the types are, etc. `1 + 1` in JS and `(i32.add (i32.const 1) (i32.const 1))` should still result in the same cpu code, the only difference is that it takes longer for the JS code to get there (and there's no guarantee that it happens to the JS code).
(and yes I know, the addition would be constant folded, it's just an example okay)
In Firefox, Wasm still uses a tiered JIT. Like JS, there is a single-pass JIT and a JIT that does more aggressive optimizations (mostly: good regalloc).
However the compilers are much simpler than the equivalent JS compilers, because wasm doesn't need on-stack-invalidation.
It sounds more useful to just ship less JavaScript code if your problem is taking too much time script parsing, etc. Especially given how bundle sizes have grown in the past few years.
Never mind that this example parses and compiles the wasm code at runtime, so it's probably not faster at all to takes chunks of JS and port it to wasm if you're going to run it this way.
This reminds me of the classic owl meme. Draw two circles, then draw the rest of the damn owl. Writing a hello world does not make WebAssembly easy. I can write a hello world in Rust or in Haskell trivially. That doesn't mean I understand borrow checking or monads. Besides the author doesn't even go over printing hello world.
In fact there's quite a lot that's inaccurate with this short article. WebAssembly is not really close to Assembly. It offers quite a lot more structure, including control flow and even a concept of functions with types. Also refactoring performance critical code in WebAssembly is not the greatest idea since there's a massive interop overhead. Not to mention hand writing WASM is incredibly tedious.
There is a good reason why we are not attempting to print a string.
Yeah, there's a good reason printing "Hello, World!" is the test. If you can't even get that far, you're going to have a hard time doing anything useful at all.
The idea is that it's the most basic example (in most instances) of ensuring your whole pipeline is setup correctly. It's the software equivalent of a smoke test.
It's hard until you have the toolchain and I/O working. That's what it's a test of. The rest of WebAssembly doesn't seem like an obstacle at all to me. For me the big unknown is how to get a wasm program running at all and communicating with something on my screen.
It is a test that you can go from written code to an output that is human readable. This is the basic steps to allow us to use printf debugging. Until you get to this point, it can be hard to be sure your code is actually working or even compiling or if you have established a way to report errors.
As other poster's have commented, for most languages the code for this is trivial but the importance is that it tests the entire compile/link/execute tool chain which may not be as trivial to setup.
There's the TPK Algorithm, but it still doesn't show off certain parts of the language, such as dynamic memory allocation or passing around references/pointers. Of course, not every language has those things, and it was invented to demonstrate precisely the kinds of languages which don't, such as Eisenhower-era FORTRAN. It does have user input as well as output, plus iteration and conditionals.
To be fair, I've written a fair amount of Rust. I haven't really gotten the borrow checker, or at least I've only fought it once or twice, and most of my data structures don't need lifetimes. And from my experience, algorithmic things generally don't require you fight it (except graphs and linked structures), which is what I would think you'd try to optimize.
----
Edit: I agree though that it's not as easy as the author makes it out to be.
Wow. If you need to use a special library made by the author, then what's the point of a hello world? You're not learning how to get the basic things running.
You should look over the article a little more carefully. The special library is only if you want to inline WASM in javascript. You can still write and use WASM without it
I'm not sure if I could say wasm is easy, but I was really impressed with how easy it was to get an emulator written in C running in the browser with Emscripten. It pretty much just worked and only took a couple hours to have it working well. I started with zero wasm/Emscripten experience.
It helped that the emulator was written with SDL and zlib, both of which have wasm implementations provided out of the box by Emscripten. Major props to the Emscripten team!
WASM is fast in execution but the time spent getting data in and out of the memory allocated by WASM so that it can do direct memory management dominates the performance gains as a slowdown.
This post is funny. “Web assembly is super duper easy! let’s do a hello world example! But also let’s not do a hello world examples because strings don’t exist in WASM and that would be kind of confusing!”
But low level languages usually are more verbose. High level languages can afford to be more terse. The WASM code looks very similar to actual x86 assembly to me, and with a name like 'web assembly', that seems right.
I really like the idea of web assembly but I haven't seen any examples of it being done well. Even this page I can't see the app running. Does anyone have any website that shows a useful web assembly running?
(I also like the idea of edge computing with web assembly but haven't seen anything good for that either)
The hard part of Web Assembly is getting data in and out. Since you can write in C and compile to WebAssembly you don’t have to learn WebAssembly. But even C doesn’t make data exchange easy. You basically pass a large array of bytes in out instead of proper high level data structures. This is what makes WebAssembly hard.
44 comments
[ 0.20 ms ] story [ 98.1 ms ] threadThere is, writing WASM by hand will not only create an unmanageable mess but also should be strongly discouraged, WASM is supposed to be a target not a “language” like the author is mentioning.
Also, it’s doubtful WASM is actually faster than plain JavaScript for most use cases when not speaking of benchmark-optimized tests. It’s not the point of WASM.
Unfortunately, the way I see it is the ASM part in WASM is going to create a disaster where people really believe it’s an analog to physical machine code.
Even speaking of proper assembly code, it’s not advisable to write it by hand except in very rare and specific scenarios such as cryptography as it’s most of the time going to be slower than using an optimizing compiler anyway.
I assume there are several use cases where WASM is faster than JavaScript, despite all the things you mention. Some types of canvas manipulation are typically faster with WASM, for example.
Of course I wouldn't write web assembly by hand normally for most projects, but I also wouldn't create a blanket rule that it should be discouraged across the board. It's another language that goes through a compile process, just a very specialized one, like assembly.
[0]: https://webassembly.github.io/spec/core/text/index.html
[0] https://webassembly.org/
(and yes I know, the addition would be constant folded, it's just an example okay)
However the compilers are much simpler than the equivalent JS compilers, because wasm doesn't need on-stack-invalidation.
In fact there's quite a lot that's inaccurate with this short article. WebAssembly is not really close to Assembly. It offers quite a lot more structure, including control flow and even a concept of functions with types. Also refactoring performance critical code in WebAssembly is not the greatest idea since there's a massive interop overhead. Not to mention hand writing WASM is incredibly tedious.
Yeah, there's a good reason printing "Hello, World!" is the test. If you can't even get that far, you're going to have a hard time doing anything useful at all.
As other poster's have commented, for most languages the code for this is trivial but the importance is that it tests the entire compile/link/execute tool chain which may not be as trivial to setup.
Several tools I'm pretty deeply familiar with still make me feel dumb because they are user-hostile.
https://en.wikipedia.org/wiki/TPK_algorithm
You are right. But if done judiciously, it can bring large benifits. The massive interop overhead has also shrunk quite a bit.
Here's a fun article about shrinking the overhead: https://hacks.mozilla.org/2018/10/calls-between-javascript-a... - IIRC, chrome as added similar optimizations.
And here's a fun article about gaining performance through rewriting in WebAssembly: https://hacks.mozilla.org/2018/01/oxidizing-source-maps-with...
To be fair, I've written a fair amount of Rust. I haven't really gotten the borrow checker, or at least I've only fought it once or twice, and most of my data structures don't need lifetimes. And from my experience, algorithmic things generally don't require you fight it (except graphs and linked structures), which is what I would think you'd try to optimize.
----
Edit: I agree though that it's not as easy as the author makes it out to be.
It helped that the emulator was written with SDL and zlib, both of which have wasm implementations provided out of the box by Emscripten. Major props to the Emscripten team!
Emulator is running here if curious: https://city41.github.io/nggm/ https://github.com/city41/nggm
https://blog.sqreen.com/webassembly-performance/
Edit:
This should have been titled "hello addition from webassembly"
Are you sure you’re not confusing the code that the author uses to demonstrate running inline code from JavaScript with the wasm code itself?
An actual `Hello World` is not too much effort to be honest (30 loc) https://gist.github.com/devsnek/18228912613de5068e448bf21a66...
(I also like the idea of edge computing with web assembly but haven't seen anything good for that either)
It's not an app but a development framework for C#. Interesting nevertheless.
https://github.com/JeremyLikness/blazor-wasm