4 ms·
> So how does this work? Before the code is deployed, as part of a build step, we run the JS code using the JS engine to the end of initialization. I also did
by kodablah 5y ago
> So how does this work? Before the code is deployed, as part of a build step, we run the JS code using the JS engine to the end of initialization.
I also did basically this exact same thing for Go [0] when I realized their initialization in WASM was very heavy[1]. Basically I ran up until the real Go main started which includes a ton of runtime package/data initialization, and took a snapshot of the data and baked it back into the WASM and removed all the pre-main code. Granted this was years ago so I don't know if it still works on generated code today, but the idea is the same.
I think languages compiling to WASM, if they can, should run their initialization code and snapshot the data. A lot of people don't realize the number of init instructions to bootstrap a runtime these days. Go alone has thousands of instructions just to initialize the unicode tables. Over 4 million instructions before main were removed from hello-world Go WASM init by pre-processing.
0 - https://github.com/cretz/go-wasm-bake https://github.com/cretz/go-wasm-bake
1 - https://github.com/golang/go/issues/26622 https://github.com/golang/go/issues/26622
- skratlo 5y agoAnd round and round we go http://www.sbcl.org/manual/index.html#Saving-a-Core-Image http://www.sbcl.org/manual/index.html#Saving-a-Core-Image
- deathanatos 5y agoWhich reminds me of Emac's unexec(): https://emacshorrors.com/posts/unexecute.html https://emacshorrors.com/posts/unexecute.html (Not sure if that's the best link, but it is easily Googleable.)
- mananaysiempre 5y ago“Format compilation” in TeX also appears to be inspired by a similar snapshotting mechanism built into TOPS-20[1]. Generally, I’d say that dumping VM state (if not in the host executable format) is a perfectly ordinary thing for an isolated VM to do. It’s the default way Smalltalk systems operate, for example, being very close ideologically to Lisp machines in that they try to be an OS centered around a programming language more than a programming language implemented inside an OS. (I should really look into that Oberon thing one of those days...) [1]: https://tug.org/TUGboat/tb26-1/beebe.pdf https://tug.org/TUGboat/tb26-1/beebe.pdf
- mananaysiempre 5y ago... Aa-and I’m being stupid, because there were of course also “persistent” OSes like KeyKOS[1], where a memory image (swapped in, modified, and swapped out as necessary) is essentially the only way for a program to exist. (Good news: capability access control is easy to program to and has entirely intuitive dynamic behaviour. Bad news: noöne has worked out how to bootstrap this dynamic behaviour from a static set of rules in a reasonably modular way, to the point that making a system which can hibernate but never shut down actually starts to look like a reasonable solution.) [1]: http://cap-lore.com/CapTheory/upenn/ http://cap-lore.com/CapTheory/upenn/
- tingletech 5y ago`perlcc` works basically the same way if I understand correctly
- hackcasual 5y agoYou want to be careful with this technique when payload size dominates your application's performance, like on a webpage. I was looking into improving Emscripten's pre-execution behavior, but found that ended up making perf worse when factoring in standard download speeds. The functions it removes are usually smaller than the data they add, usually with worse entropy. So while JS is faster to execute, it's usually not faster than the transfer time. It gets a bit worse if your initialization code is doing a lot of dynamic allocation, as you're shipping
- Softcadbury 5y agoFor the first call maybe, but then with the cache ?
- wffurr 5y agoYou can't ever rely on the browser cache. Hit rates are very poor. Unless maybe you're managing cache yourself with a service worker.
- jfrunyon 5y agoThat depends entirely on what you're developing (internal vs external etc.) and how frequently the resource will be needed.
- hackcasual 5y agoYou're really only saving a few milliseconds, and keeping cached files small is valuable.
- bitwize 5y agoThis is also how Emacs optimized its startup: by loading its initial Emacs Lisp code and dumping itself together with a heap snapshot into a new executable (there is a special API in glibc to do just this). Recently Emacs has moved to a "portable dump" approach which saves the heap snapshot separately.
- sitkack 5y agoThis is a wonderful read on the "portable dumper" https://lwn.net/Articles/707615/ https://lwn.net/Articles/707615/ https://web.archive.org/web/20191030205003/https://dancol.org/pdumperpres.pdf https://web.archive.org/web/20191030205003/https://dancol.or...
- cryptonector 5y agoSo dump post init, kinda like emacs used to.