4 ms·
Congratulations to the Nim team! I did a quick comparison between the up and coming compiled languages (D, Rust, Nim, Go) and C++ a week or so back. My main ai
by Cyph0n 12y ago
Congratulations to the Nim team!
I did a quick comparison between the up and coming compiled languages (D, Rust, Nim, Go) and C++ a week or so back. My main aim was to assess the final statically linked binary size for a simple hello world program.
Here are the results on x64 Mint:
1. C++: 1.6 MB
2. Go: 1.9 MB
3. Rust: 550 KB with dependencies (I was not able to figure out how to pass a static option to rustc)
4. D: 710 KB, same as Rust
5. Nim: 970 KB, statically linked
Nim wins, by a large margin. I did not remove any of the runtime checks by the way. Removing them actually saves 100 KB+, depending on the program. Furthermore, the Nim program was actually a naive Fibonacci number calculator, not a simple hello world, meaning that Nim should have been at a disadvantage! Amazing stuff.
- kevinnk 12y agoFor C++ most of that is iostream. $ cat hello.cpp #include <cstdio> int main(void) { puts("Hello, World!"); } $ g++ -static hello.cpp $ du -h a.out 857K a.out Compiling for size (-Os -fdata-sections -ffunction-sections hello.c -Wl,--gc-sections) gives 816K With iostream I get 1.6M
- Cyph0n 12y agoInteresting point. It makes sense to use stdio.h in applications where size is the priority.
- yoklov 12y agoOr where performance is a priority, in my experience. iostream is both slow and bloated. ... I don't like it's API either (it's a horrible abuse of operator<<, and is the exact kind of thing you tell people not to do with operator overloading...)
- Cyph0n 12y agoDoes stdio.h work well with std::string? Or do you mean dumping strings entirely and just working with char arrays?
- yoklov 12y agoI just meant iostream. std::strings work fine with cstdio via std::string::c_str(). (e.g. printf("%s\n", some_string.c_str() works fine). That said, I tend to avoid std::string as well, due to other performance issues (you tend to have a lot of copies and lots of heap allocations you don't really need). That said, I work in game development, and don't have to do much string processing, and someone in another domain might find this more painful than I do.
- e12e 12y agoI had to check, but apparently that'll work for utf8 on posix (windows not so much) with unicode literals and std=c++11 (or higher presumably). Nim assumes utf8. For c++: puts(u8"World is not spelled 'wørld'");
- gtaylor 12y agoThat's cool, but with disk space and memory being as cheap as they are, is this still a big deal in anything but the smallest of embedded environments?
- joshuapants 12y agoIt's small with a small program, but for something substantially larger it can certainly make a difference
- Cyph0n 12y agoI think this kind of thing demonstrates portability at a lower cost and better compile-time optimizations. You would think the other languages, especially C++ and Rust, would do better in the latter.
- oldmanjay 12y agoOptimizing for size often has an inverse impact on runtime, for instance if the compiler would have inlined heavily. edit: tense clarification
- pcwalton 12y agoThe real problem is that glibc has a hard time being statically linked. We just use the native system C library in Rust, which on Linux is usually glibc. We could focus on musl support in order to get true static linking, but there are much higher priority things like 1.0 stability, optimizations, and compiler performance (though we'd take a patch of course). The fact is that pure static linking is rarely done anymore, at least on mainstream desktop/mobile/server systems, so it's not on anybody's critical path. Dynamically linking to glibc does not really provide "better compile-time optimizations". LLVM already understands the libc functions that really benefit from inlining, like memcpy.
- 23david 12y agoI agree that disk space has gotten a lot cheaper, but bandwidth speed hasn't increased tremendously. Binary sizes definitely are an issue. And re:memory, it's pretty tight on most end-user machines. By default, most laptops only come with 4-8GB of RAM. And in the cloud, memory cost is perhaps even more expensive. On ec2, a 'large' instance usually has only between 4-8GB of RAM. The default small instances have only 2GB of RAM, which doesn't give much room left over for applications after you account for the OS and various utilities. It can definitely add up.
- steveklabnik 12y ago> (I was not able to figure out how to pass a static option to rustc) We statically link by default, actually: https://gist.github.com/steveklabnik/e9e744d23a7a14edcd47 https://gist.github.com/steveklabnik/e9e744d23a7a14edcd47 Everything but glibc. Experimental support for musl landed a few days ago. You can take this _really_ far: http://mainisusuallyafunction.blogspot.com/2015/01/151-byte-static-linux-binary-in-rust.html http://mainisusuallyafunction.blogspot.com/2015/01/151-byte-...
- Cyph0n 12y agoYeah, I saw that article. Damn cool stuff. That's why I'm confused about static linking in Rust. Am I doing something wrong? http://i.imgur.com/gtlJoO0.png http://i.imgur.com/gtlJoO0.png
- steveklabnik 12y agoThat's the glibc stuff I mentioned above. You generally don't statically link glibc. I don't have the setup to try out the musl stuff, but there's instructions here: https://github.com/rust-lang/rust/pull/24777 https://github.com/rust-lang/rust/pull/24777
- apta 12y ago> 4. D: 710 KB, same as Rust > 5. Nim: 970 KB, statically linked > Nim wins, by a large margin. 970 KB > 710 KB.
- cornstalks 12y agoBut 970 KB < 710 KB + larger dependencies. Both Rust and D have dependencies, as mentioned by the parent comment. You can argue whether or not the dependencies should be included in an executables size, but I think the comment is trying to show that Nim can create a complete program (with no dependencies) with less space.
- Cyph0n 12y agoI mentioned that I couldn't get a fully static binary with Rust and D.
- zem 12y agosounds like the D binary was not statically linked.
- Cyph0n 12y agoIt was not. I couldn't find the correct compiler flag.