12 ms·
> I've watched friends try Go and immediately uninstall the compiler when they see that the resulting no-op demo program is larger than 2 MiB. That seems a bit
by NikolaeVarius 5y ago
> I've watched friends try Go and immediately uninstall the compiler when they see that the resulting no-op demo program is larger than 2 MiB.
That seems a bit extreme
> Overhead breeds complacency — if your program is already several megabytes in size, what's a few extra bytes wasted? Such thinking leads to atrocities like writing desktop text editors bundled on top of an entire web browser
I'm still on board
- imoverclocked 5y ago> I'll allow it. ABI compliance is a very good reason for "wasting" 3 bytes of code, and should arguably be added to our original assembly program I guess we all have some set of scope creep that we take as OK. ABI compliance for some, GC or other niceties for others, and then there is anything node/electron based.
- unbanned 5y ago
- JulianMorrison 5y agoI'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.
- xyproto 5y agoWhich Go compiler? gccgo produces smaller executables.
- deleted 5y ago[deleted]
- stephc_int13 5y ago>That seems a bit extreme Not to me, I would have done the same. And I tend to look at the binary size of simple programs to get a first taste of the style of tech I am looking at. Bloated binaries and slow compilation time are red flags in my book, I use them as simple heuristics to avoid losing too much time. I know it is not perfect, but it is fast and simple, like all good heuristics.
- Aransentin 5y agoThis was pretty much it. (I am the author) People do low-commitment exploration of new tech all the time, perhaps offhandedly download some new language compiler to see what all the fuss is about. Even a modestly negative experience can easily tip the scales for them to lose interest and go do something else.
- chespinoza 5y agoYou have to consider that go users can come from worst places(i.e. Java or Interpreted dynamic languages) so just getting a statically compiled binary to deploy it's already a big improvement.
- 1_player 5y agoIt's fast and simple but not a good heuristic. It's like judging a car by how expensive it is. It has nothing to do with how the thing performs. Optimising for size is such a waste of time in this day and age. I know I would rather choose a 5 MB statically linked binary than a 5 KB dynamically linked one, because they take pretty much the same amount of perceived time to transfer over the internet, yet the smaller file might take more of my time because I need to find and install missing dependencies. On the list of priorities for language developers, size optimisation is towards the bottom, unless we're talking about embedded but we aren't.
- int_19h 5y agoCompiling dynamically is not really optimizing for size, since you have to include size of said dependencies. As far as whether size matters - it really depends. Some parts of the world are still mostly on dialup (or very slow mobile).
- deleted 5y ago[deleted]
- jasone 5y agoI remember one of my first experiences with Facebook's HPHP, compiling a "hello world" PHP program. I can't remember anymore whether the binary was over 20 MiB or over 200 MiB (both seem plausible in retrospect!), but I do remember the existential dread that ensued. In my experience, massively bloated binaries should instill only slightly less fear than brittle ocean-boiling build systems. Tears will surely result from either.