4 ms·
What 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
by spicybright 5y ago
What 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.
- adgjlsfhk1 5y agoPretty much all programs use the GC. Threading isn't used in everything, but Go, especially probably has at least 50% of programs over 1000 lines use threads (especially considering the standard lib).
- JulianMorrison 5y agoIf I remember right the GC lives on a thread, even if the program runs serially.
- jrockway 5y agoI use tinygo on microcontrollers and use channels. It's simpler than an RTOS.
- dgellow 5y agoLink for those interested: https://tinygo.org/ https://tinygo.org/. > TinyGo brings the Go programming language to embedded systems and to the modern web by creating a new compiler based on LLVM. > You can compile and run TinyGo programs on over 60 different microcontroller boards such as the BBC micro:bit and the Arduino Uno. > TinyGo can also produce WebAssembly (WASM) code which is very compact in size. You can compile programs for web browsers, as well as for server and edge computing environments that support the WebAssembly System Interface (WASI) family of interfaces.
- AnIdiotOnTheNet 5y agoI wrote a Gigatron emulator in Zig for Win32. Compiled with ReleaseFast (not even ReleaseSmall!) it is only 446KB. The full-fat debug version is only just over a MB. 2MB is a lot for a binary.
- spicybright 5y agoIs it really though? 2mb is practically nothing on modern machines. And full-fat debug should have as much info as it can, why optimize it unless you're spitting out 400+mb binaries or something crazy. It's like, yes, if you turn off the A/C in your muscle car, you'll technically get a few extra horse power. But past some philosophical ideal of squeezing out every bit of horse power you can, it has a negligible effect on the operation of the car. Now if you're working on a weed wacker engine or something, yeah that would matter. But you wouldn't pick a giant beefy engine and expect it to work as well as a tiny lightweight one.
- titzer 5y ago> 2mb is practically nothing on modern machines. There are plenty of embedded systems that have <= 1mb of memory. E.g. a popular one is Teensy (https://www.pjrc.com/store/teensy40.html https://www.pjrc.com/store/teensy40.html).
- AnIdiotOnTheNet 5y ago> Is it really though? 2mb is practically nothing on modern machines. In general, I agree actually. I think hemming and hawing over duplicated shared libraries in particular makes no sense for most modern systems. Still, 2MB is a pretty damn big overhead to put on every binary the way Go does. Not that it isn't a considered trade off or anything, I'm just saying. > And full-fat debug should have as much info as it can, why optimize it unless you're spitting out 400+mb binaries or something crazy. That's my point: there's no optimization in the full-fat debug and it does contain everything it can and it's still a little more than half the size of a completely empty Go binary. 2MB is huge. For the ReleaseFast version all I did was tell the compiler to optimize for speed and otherwise put no effort into making anything size efficient.
- titzer 5y ago> What 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. I'm not so sure about that. A lot of embedded systems software works well without allocating any memory at runtime at all. Particularly microcontroller programs. The first version of Virgil targeted AVR (via codegen to C) and did exactly this; allocate all data structures up front, at compile time, and then bake them into the binary. This is still common in realtime systems. No dynamic memory allocation = no garbage collector, no non-deterministic allocation/deallocation, no write barriers, no out-of-memory possibilities, no fragmentation. For a surprisingly large class of programs, this is a great situation! > So why waste the effort putting in a code path to disable these things except for some philosophical ideal? Virgil in particular, does the opposite; it only includes what the program uses. The analysis starts with nothing and then brings in things called and used from main, tracing through those new things, etc, until the transitive closure is included. Unreachable code isn't even seen, except by the parser and semantic checker, so it doesn't get included. Although, admittedly, the GC is a little special in that a single allocation in the program will drag in most of it. And most programs accept command-line arguments, which the default runtime boxes up into an array of strings for "main()", so most programs do end up with the GC included. You can turn that off with a flag or by modifying the runtime startup code (e.g. squirrel away the arguments array pointer and count, pass null to "main()", and parse the arguments as raw pointers without allocating. (but yuk.)
- sitkack 5y ago> No dynamic memory allocation = no garbage collector, no non-deterministic allocation/deallocation, no write barriers, no out-of-memory possibilities, no fragmentation. For a surprisingly large class of programs, this is a great situation! I know you know this already, but your statement is a little too broad. Those problems all still exist, but are greatly reduced. Data structures still need to be compacted, caches evicted, scratch space cleared, etc. It is just that one class of intractable issues gets removed when dynamic memory allocation goes away. On a side note, have you seen this? https://github.com/udem-dlteam/ribbit https://github.com/udem-dlteam/ribbit https://www.youtube.com/watch?v=A3r0cYRwrSs https://www.youtube.com/watch?v=A3r0cYRwrSs an extremely compact VM for a version of R4RS.