Will the binaries be compiled for size optimization, or will they be the same size as usual golang bins?
Go binaries, being static and embedding the whole go runtime, tend to be quite big. Now, I don't care about it because 5 or 10MO on my server filesystem is nothing. If I ask every visitor to download 10MO before running my webpage, that will be a problem, though.
Is this something we will have to deal with? Or will this be a lesser featured go implementation?
Half the size of Go binaries you encounter in the wild are debugging symbols. Compile without them and use `upx --ultra-brute` and the binary will be about ~15% of its original size. You still get goroutine stack traces from panics without the debugging symbols.
Even building without debugging symbols, a lot of the remaining size comes from runtime type information and method/function/struct names, used in reflection, which there's no way to remove. That also has some reverse-engineering implications.
I didn't know go compiler allowed to build without those, thanks.
I've just tried on a go binary that was 2.4MO. After building it with `go build -ldflags=-s .`, it's 1.6MO. After stripping with upx, it's 480ko (and still works, and has panic stack traces).
Please note that upx also compresses your binary contents and decompresses it at runtime.
When downloading a WASM file over HTTP, the server can gzip it transparently. It'd be interesting to compare the effects on the size with what upx does (which is more specialized than gzip).
I see, thanks. I used vanilla `strip` on my binary and it did not produce any size gain (so the strip flag of go compiler is plenty enough).
Indeed, given how browsers already handle gunziping resources, it's probably best to rely on it. My binary, stripped by the go compiler and gziped, is 525ko (against 480ko using upx).
I remember UPX packed binaries would trigger some antivirus software in the past because packing was so frequently used by virus authors. Does anyone know if this is still the case?
Also, can you use UPX on WebAssembly binaries? If so, will that trigger any widely used antivirus software?
UPX just compresses the machine code on disk and decompresses it in memory before execution. WebAssembly executables are delivered via http and can just be compressed with gzip/brotli etc as part of the existing protocols, completely transparently to WA itself.
Granted, UPX is specialized so it might have a slight compression edge over gzip. But layering UPX over WA will require three passes over all the code before it's ready to start (1: browser downloads and executes UPX stub and compressed data. 2: UPX unpacks and reloads uncompressed code. 3: browser re-compiles and executes unpacked code again.) This would completely decimate browsers attempts to make WA startup fast like firefox's streaming compiler [1] that starts compiling it before it's even done downloading.
I don't know much about wasm, but I imagine that most wasm binaries will be statically linked. The runtime does add overhead but I'd like to know how much compared to what you see with reasonably complex rust wasm code.
Yeah indeed, and if web development prefigure anything for wasm, we can expect apps to quickly have a lot of dependencies built in. I guess we'll get used again to "please wait, loading" screens :)
Hmm, maybe language runetimes can be dynamically linked and hosted by the language maintainers. Everyone imports the official library so the odds of the user already having most of everything cached is high.
Hey so question - WebAssembly can't access the DOM right? What's the whole point then, avoid Javascript? If we can't just swap out all the gnarly JS garbage whole-hog, I don't see where the business value is, given that there's plenty of language-to-js libraries.
So there's a lot of other things that can be done on the client other than interacting with the DOM. In particular, applications that render intense graphics, or manage a local database could GREATLY benefit from more efficient compiled code, and this would open up possibilities that the current JS engine wouldn't be able to deliver.
That's indeed true, but I wouldn't count Go as an example of “efficient compiled code”. It's way behind of GCC or LLVM in terms of optimizations, and being ahead-of-time-compiled is a drawback, not an asset.
About llvm, there's a WIP prototype that doesn't quite work yet[0].
And about GCC, GccGo is behind in Go's version. GCC 7 only supports Go 1.8 (with caveats). Also, it had issues at some point[2] (but this is from 2014, it may have been fixed since then).
And, on a more pragmatic point of view, when talking about Go, the huge majority talks about Go compiled with the standard Go compiler. That's why you here a lot of positive feedback about compile-times for instance.
Twitch rewrote their entire video player in C++ and compiles it down to WebAssembly with Emscripten. That way the same player can be compiled to the web, as to iOS, Android, game consoles etc. That’s a huge business case when you want to create a module to support a wide variety of platforms and targets.
Webassembly uses a javascript "glue" for accessing the DOM. The point of Webassembly is not to just be an alternative to javascript; it's to have a binary web program format that runs at close to native speeds. This makes it extremely useful for porting C/C++ applications, especially games, to the browser.
It can be a lot faster and less memory-hungry than javascript. That opens up a lot of things you can't feasibly do in JS. Game engines, image decoding, even video editing. http://webassembly.org/docs/use-cases/
Article mentions that the compiled code will also run on Node.js, does it mean it will be possible to use all zillions of NPM modules from Go at some point in time?
> Currently WebAssembly has no threads, but they are on the roadmap. Most Go code can run fine on a single thread. The only drawback is that “sysmon” is not available, thus there is no preemption of goroutines.
Go does both preemptive and cooperative multitasking, so there is no relation to the number of goroutines "running" and the number of threads (or for that matter, cpus or cores).
How this works in Go ? Thoroughly simplified it happens because at every flow control statement in Go, including function calls, what really happens is that, first, Go asks it's runtime to switch goroutines, and only then goes into the if, or subroutine, or ...
I believe that the LLVM project is trying to accomplish this [1].
However, the concurrent, non-pausing GC of GoLang is not easy to match in efficiency. I'd be interested to hear about actual high-quality implementations of GCs in LLVM.
And then there's the problem of making it all work efficiently in WASM (which doesn't yet support advanced concepts needed by GCs such as memory barriers).
Tracing objects in the heap (and/or stack). The GC has to be able to find all the outgoing pointers from any object, and usually the types of the objects pointed to by those pointers as well. Different language runtimes store objects in memory in different ways.
I think the interface can provide the semantics - pass by reference or value etc. Which can be standardized. Then it is upto the languages to implement the interface.
IMO the languages designers and developers are better off by looking at the GC solution from top-down rather than bottom-up.
Maybe you should think about what this would mean from the perspective of language designers. That would unearth the main difficulty of such an approach:
Every language designer would have to completely redesign it's runtime system just to be able to run on this one backend (in addition to having a new compiler target and linker and debugger and ...). Hoping, of course, that this is possible at all, as many languages have various ways to store pointers to things in memory, which including not storing one at all (ie. pointer arithmetic).
Why would they do this ? Why should they do this ? You could simply make the existing runtime libraries run.
> Why would they do this ? Why should they do this ?
One answer could be that it would enable multiple languages to interface in a better way, and allow garbage to be collected across language boundaries.
allocation characteristics of different languages. Go copies when passing args. java is pass by value, but those values are usually pointers to objects. very different needs.
WebAssembly doesn't provide any functional capabilities that aren't already accessible to JavaScript. This change does not really enable a browser to do anything more "natively" than it already could, other than run code that's written in Go.
In case you didn't see recently, https://github.com/grpc/grpc-web came out of hidden-repo status recently. Of course there are caveats to its use, but I believe a server side gateway may always be needed due to how http/2 is used but I'm unsure.
I really wish WebAssembly did not use the word "Assembly". It doesn't really resemble any actual assembly language. And if you look at the comments in this thread, for example, a lot of people think it's letting you have something like arbitrary machine code.
Especially with upcoming features like GC, threads, exceptions, polymorphic inline cache, and more[1]. Looks somewhere in between ASM and something like bytecode for a VM.
Well, ASM is a bytecode for a VM too … CPU are really complex theses days and you definetly don't run your asm on a dumb piece of silicon, as the phrase “bare metal” seams to imply.
And, as a reminder, there's often bugs in that VM. Meltdown was one of them, but there's tons of them.
I really wish WebAssembly didn’t use the word “Web”. Its best usecase is for the server. It just happens to also be great for challenging JavaScript in the browser.
Why do you say its "best" usecase is for the server? I'm actually asking, not disputing, but I'm asking because it seems the big selling point of WASM, running new types of code that you couldn't run before, was never a problem on the server, where you can run whatever you like.
So, I'm assuming you have something else in mind, and I'm wondering what it is.
This is great; looks like it's still fairly rough but interesting that GC languages are making due with what's there in the MVP of WebAssembly right now.
Wonder how it works? does it use the regular call stacks or construct it's own and so on?
> Go’s garbage collection is fully supported. WebAssembly is planning to add its own garbage collection, but it is hard to imagine that it would yield a better performance than Go’s own GC which is specifically tailored to Go’s needs.
Presumably a runtime will be compiled into the wasm output, including Go's garbage collector.
I think it's certainly possible. The Go compiler is AOT and there are Go interpreters (in various stages of completeness), it would be a matter of interpreting the application - finding hot functions in execution traces - and swapping them out with background-compiled versions.
Some work would be needed to keep the GC happy between interpreted and compiled functions, but no more complex than JS JITs have to do. Go's GC at least already has the capability to move objects, that's a help.
In reality, JITs are used to infer typing information that dynamic languages only discover at runtime. Go doesn't have this problem, and an AOT can probably discover stronger optimizations.
Go binaries, being static and embedding the whole go runtime, tend to be quite big. Now, I don't care about it because 5 or 10MO on my server filesystem is nothing. If I ask every visitor to download 10MO before running my webpage, that will be a problem, though.
Is this something we will have to deal with? Or will this be a lesser featured go implementation?