That said, a trivial “Hello World!” isn’t a meaningful benchmark. If you’re going to play that game, you might as well swap `fmt.Printf` for `fmt.Println`, or even `println` to avoid the import statement entirely. At that point, you’re no longer comparing anything interesting, the binaries end up roughly the same size anyway.
Writing embedded code with an async-aware programming language is wonderful (see Rust's embassy), but wonder how competitive this is when you need to push large quantities of data through a micro controller, I presume this is not suitable for real-time stuff?
I've written a fair amount of code for EmbeddedGo. Garbage Collector is not an issue if you avoid heap allocations in your main loop. But if you're CPU bound a goroutine might block others from running for quite some time. If your platform supports async preemption, you might be able to patch the goroutine scheduler with realtime capabilities.
Definitely don't recommend that since it works when it does and doesn't otherwise. Most users will not end up happy trying to make it work since the alternative is more common.
This isn't a fault of TinyGo itself, it is just targeting a space that doesn't really prioritize embedded but got picked up for that just because. But without fixing this Wasm ecosystem issue, compiling Go to Wasm will never be a real thing.
If you are in an embedded world, the tradeoffs are quite mild. Mostly these center around library availability and that is often gated by use of reflection.
If you are thinking that this is a way to support mainstream go programming, you will be sorely disappointed.
Its a fantastic project, but seems almost inactive now. I have a tiny PR pending for weeks, even reviewed, but not merged. I have another patch I have not submitted as I want to first navigate the earlier PR to completion. Both were bugs that bit me, and I ended up wasting quite a lot of time trying to find it:
1. go:embed supports "all:<pattern" while tinygo silently ignore it. I ripped my hair out trying to figure out why my files were not showing up in embedfs. PR pending.
2. go allows setting some global vars at the build cli (think build version/tag etc). In the code, one can define a default, and then the value provided (if any) on the cli can override it at build time. Tinygo fails to override the value at build-time, silently, if a default value is provided for the var in code. This PR I have not submitted yet, as its more intrusive.
I hope it picks up steam again soon. I love using go for embedded and CF worker use and tinygo makes both of these use cases much more viable than regular go. Honestly, I hope tinygo can be rolled over into the main go toolchain as "target arch".
TinyGo was instrumental in getting https://github.com/rcarmo/go-rdp to work. It generates very tight, pretty high performing WASM, and that allowed me to push all the RDP decoding to the browser side while making sure I had a sane test suite. Heartily recommended.
23 comments
[ 4539 ms ] story [ 2365 ms ] threadIt does indeed produce much smaller binaries, including for macOS.
• 2581616B (2.5MB) → 1714560B (1.6MB) (with -ldflags="-s -w")
• 1531920B (1.5MB) → 753680B (0.7MB) (with upx --force-macos)
That said, a trivial “Hello World!” isn’t a meaningful benchmark. If you’re going to play that game, you might as well swap `fmt.Printf` for `fmt.Println`, or even `println` to avoid the import statement entirely. At that point, you’re no longer comparing anything interesting, the binaries end up roughly the same size anyway.
Hardware-level async makes sense to me. I can scope it. I can read the data sheet.
Software async in contrast seems difficult to characterize and reason about so I've been intimidated.
I use that capability, for instance, in go-wspr [1] to get very nice low-jitter timing for frequency corrections.
[1] https://github.com/tdunning/go-wspr
This isn't a fault of TinyGo itself, it is just targeting a space that doesn't really prioritize embedded but got picked up for that just because. But without fixing this Wasm ecosystem issue, compiling Go to Wasm will never be a real thing.
https://github.com/WebAssembly/gc/issues/59
If you are thinking that this is a way to support mainstream go programming, you will be sorely disappointed.
[0] https://github.com/tinygo-org/tinygo/issues/4880
[1] https://github.com/Nerzal/tinywebsocket
1. go:embed supports "all:<pattern" while tinygo silently ignore it. I ripped my hair out trying to figure out why my files were not showing up in embedfs. PR pending.
2. go allows setting some global vars at the build cli (think build version/tag etc). In the code, one can define a default, and then the value provided (if any) on the cli can override it at build time. Tinygo fails to override the value at build-time, silently, if a default value is provided for the var in code. This PR I have not submitted yet, as its more intrusive.
I hope it picks up steam again soon. I love using go for embedded and CF worker use and tinygo makes both of these use cases much more viable than regular go. Honestly, I hope tinygo can be rolled over into the main go toolchain as "target arch".
https://github.com/tinygo-org/tinygo/commits/dev/
Maybe the opposite thing is happening, whereby the maintainers are getting overwhelmed?
Consider joining the slack channel #tinygo-dev on gophers.slack.com and pinging them about the PR.