6 ms·
I'm imagining that the Go people would have a hard time making the compiled program smaller, because they're bundling in a M:N threading system, inter-thread ch
by JulianMorrison 5y ago
I'm imagining that the Go people would have a hard time making the compiled program smaller, because they're bundling in a M:N threading system, inter-thread channels, a garbage collector, a stack resizer, a syscall parking and reactivation system, and all of the above are by necessity mutually interdependent.
- jaytaylor 5y agoPerhaps functional chunks could be excluded from the final emitted binary when they're unused / unreachable from main? How hard would it be to check the AST for a go program's usage of channels, goroutines, etc at compile time? As these are features not used by the go language itself, it seems nearly trivial (no jit or other super dynamicism).
- JulianMorrison 5y agoThe GC needs to mess with and start and stop and throttle threads. The threads resize their stacks and that needs to talk to the GC. System calls park and restart threads. And so forth. If you use any of it you'd need all of it.
- jaytaylor 5y agoYes, the idea is if you want to use X (e.g. the GC), it comes with the binary. Otherwise exclude it. I'm proposing splitting the functional blocks into distinct pieces and including only what is actually needed in the final binary. For the case of the GC, if your go program somehow avoids all allocations (wtf??? Empty main perhaps - a seemingly stupid case), perhaps it could be excluded.
- Kwpolska 5y agoHere’s the classic story of when code can live without GC: https://devblogs.microsoft.com/oldnewthing/20180228-00/?p=98125 https://devblogs.microsoft.com/oldnewthing/20180228-00/?p=98... A very basic “Hello world” could also be GC-less and just let the OS reclaim all memory when it terminates.
- JulianMorrison 5y agoYes, I understand the idea, the point I'm making is that the runtime is a monolith, it can't be split because each piece has necessary and irreducible connections to the other pieces.
- jaytaylor 5y agoAh, gotcha. Thanks for patiently clarifying :)
- spicybright 5y agoWhat irks me most about people that complain about large binaries for empty programs is that every program past Hello World will actually use all these features. So why waste the effort putting in a code path to disable these things except for some philosophical ideal? Code in Asm or C if you need a hello world that can fit on a floppy disk, you're not really doing anything substantial anyways... There's plenty of acceptable middle ground between Go binaries using 2mb minimum and full electron apps eating your ram.
- kevin_thibedeau 5y ago> every program past Hello World will actually use all these features. Not on embedded.
- cweagans 5y agoThis is a bad argument for the same reason that "my yacht can't be used for cross country road trips" is a bad argument. You're 100% not going to use the normal Go compiler for embedded development. It's not a use-case that was considered nor engineered for. TinyGo supports it, but they built a new compiler to support that use-case.
- krona 5y agoNot paying for what you don't use is not an unreasonable goal of a compiler, linker etc.
- JulianMorrison 5y agoIt is an unreasonable goal if (1) it's wildly outside the expected use cases and (2) it complicates things. Both of which would apply.
- cweagans 5y agoSure. But as stated previously, even a basic hello world go program does use the runtime.
- masklinn 5y agoThe main issue is none of these though, it's that Go's DCE is generally quite bad so any package you import will lead to significant increases in binary size. `fmt` is (or was) a big one in every sense of the word, and why using the `print` and `println` builtin functions was sometimes a workaround (probably still is): a few years back, converting a `fmt.Print` call to `print` would save you a cool megabyte (if that was the only cause for importing fmt obviously). I've always expected that was a major reason for the Go compiler being so anal about unused import, it's essentially making the user perform DCE.
- imoverclocked 5y agoExactly, if it’s not enforced, people often neglect it. As projects grow, so do unnecessary dependencies.