4 ms·
> If you don't mind 20KB of string formatting code So this here is sort of why I brought up binary size. I know hello world size doesn't really say anything ab
by lhorie 6y ago
> If you don't mind 20KB of string formatting code
So this here is sort of why I brought up binary size. I know hello world size doesn't really say anything about real world, but as I was looking at different languages, a common theme was this defensive "well what d'ya expect from a thing that has [list of features]" tone when the question of binary size got brought up and people didn't know how to make it smaller. A normal rust build has a similar feel. The 8kb binary link above reads a bit like a hacking adventure to unravel the mysteries of yonder.
When I read stuff like this
By using a C entry point (by added the #![no_main] attribute) , managing stdio manually, and carefully analyzing which chunks of code you or your dependencies include, you can sometimes make use of libstd while avoiding bloated core::fmt.
Expect the code to be hacky and unportable, with more unsafe{}s than usual. It feels like no_std, but with libstd.
I'm undoubtedly awed at the cleverness of it all, but it's clearly way off the beaten path.
I should note that in addition to the zig build command being guessable by a newbie reading through --help, the hello world code itself is also the idiomatic thing a newbie would've reasonably written. And there's really no need for "air quotes", I really put no effort whatsoever in optimizing: I didn't even use `-O ReleaseSmall`
Among all the languages I looked at, Zig was somewhat unique in taking a default stance of proactively using compile time as a tool to take stuff away from the binary (in a sort of saint-exupery way).
I'm sure with enough effort it's possible to bring down binary sizes for most languages, but not many languages do this with the relentlessness that zig does out of the box.
- Dylan16807 6y ago> So this here is sort of why I brought up binary size. I know hello world size doesn't really say anything about real world, but as I was looking at different languages, a common theme was this defensive "well what d'ya expect from a thing that has [list of features]" tone when the question of binary size got brought up and people didn't know how to make it smaller. Well, what do you expect? How much size does printf add to a Zig binary? > When I read stuff like this You can get the vast majority of the size savings without any of that stuff. This is someone trying to find the absolute minimum, starting with very practical suggestions before getting into itty bitty weeds. I'd suggest pretending the no_main and no_std sections don't exist. Getting down to 50KB or 30KB is just a matter of telling the compiler to optimize for size and stripping unwind information. If you want to keep all the unwind code and information I'm not sure how much space it takes. > with enough effort I will note again that the compiler settings in this repo, while they may be in multiple places, are still a very small one-time effort for a program.
- lhorie 6y agoWell, it's not so much about expectations about byte counts per se. YMMV but in my experience, for whatever reason the relative size of an average program happens to correlate with how big and complex a project gets as a function of its growth. For example, the Factor distribution is some 700MB and unsurprisingly a hello world image is also huge. A while back I also saw one analysis about jquery/vue/angular/react sites and curiously framework size was also a good predictor of average app size in the wild. So I use the size metric as a coarse proxy for "complexity required to accomplish the task at hand". And if one is to believe the mantra "to be fast, do less stuff", then my instinct is to look for technologies whose proxy metric (i.e. idiomatic hello world size) is small. Maybe there are better ways to measure this, but so far this heuristic has worked for me. > How much size does printf add to a Zig binary? It depends, because comptime. Basically, it emits different code depending on the types of the params being passed in. For hello world, it wouldn't include itoa logic, for example. The irony here of course is that zig could in theory compile to a very very large binary if it had a very very large number of printf calls, all with different permutations of types. But the thing is that to a zig developer, it's clear that this is explicit static polymorphism getting compiled into a plethora of monomorphic callsites. One could implement the equivalent of go's `interface {}` underlying {type, value} tuple and have a single polymorphic function at runtime if that's what they wanted. But this same argument about how it would require someone manually implementing such a thing goes both ways: it also means that most other possible things are likely not going to be hanging around quietly adding complexity under the rug (not saying this is the case w/ rust, but it is with various other systems).
- volta83 6y ago> But the thing is that to a zig developer, it's clear that this is explicit static polymorphism getting compiled into a plethora of monomorphic callsites To a Rust programmer it is clear that the toolchain defaults are set up to satisfy the 99.99999999% of programmers whose goal isn't to "write the smallest hello world possible". You can change these defaults in your system config if you don't like them. Like you mention, one size doesn't fit all. To me that's one of the main differences between Zig and Rust.