DEV Community

loading...
Cover image for Executable Size: Rust, Go, C, and C++

Executable Size: Rust, Go, C, and C++

aakatev profile image Artem ・2 min read

I had never been curious on how the compiled languages compare in term of the binary sizes, until recently, when I started digging into C compilation process. In this article, I want to share results of my recent experiment. The Hello World programs in C, C++, Rust, and Go were compiled with static linking. The resulted executable were compared against each other.

The system used for the testing is Ubuntu 18.04, with the following version of the software:

  • gcc/g++ 7.5.0
  • go 1.15.1
  • rustc 1.46.0

Let's look at the results!

Rust

main.rs

fn main() {
  println!("Hello World!");
}
Enter fullscreen mode Exit fullscreen mode

compile

rustc -C target-feature=+crt-static main.rs
Enter fullscreen mode Exit fullscreen mode

result

2844808 Bytes

Go

main.go

package main

import "fmt"

func main() {
  fmt.Printf("Hello World\n")
}
Enter fullscreen mode Exit fullscreen mode

compile

go build -ldflags=-w  main.go
Enter fullscreen mode Exit fullscreen mode

result

1543579 Bytes

C

main.c

#include<stdio.h>

int main() {
  printf("Hello World\n");
}
Enter fullscreen mode Exit fullscreen mode

compile

gcc -static main.c
Enter fullscreen mode Exit fullscreen mode

result

844704 Bytes

C++ (Version 1)

main.cpp

#include<stdio.h>

int main() {
  printf("Hello World\n");
}
Enter fullscreen mode Exit fullscreen mode

compile

g++ -static main.cpp
Enter fullscreen mode Exit fullscreen mode

result

844704 Bytes

C++ (Version 2)

main.cpp

#include <iostream>
using namespace std;

int main() {
    cout << "Hello, World!" << endl;
}
Enter fullscreen mode Exit fullscreen mode

compile

g++ -static main.cpp
Enter fullscreen mode Exit fullscreen mode

result

2254920 Bytes

Results Table

Language Executable Size, Bytes
Rust 2844808
Go 1543579
C 844704
C++ 844704
C++ (native features) 2254920

Of course, this test is not an objective way to judge the languages. However, it gives you a good understanding of the size of each runtime. I was surprised that Go executable is smaller than C++ with native features. Also, compiler, like gcc/g++, is intelligent enough to tell whether the features are used or not.

Discussion (4)

pic
Editor guide
Collapse
aghost7 profile image
Jonathan Boudreau

Rust supports different compilation profiles targeted at embedded development. You can read more about it here: docs.rust-embedded.org/book/unsort...

If binary size is a concern, you can reduce it further with rustc -C opt-level=s -C target-feature=+crt-static main.rs.

Collapse
aakatev profile image
Artem Author

That's good to know. Next time, I will make a comparison with different levels of optimization for all the languages.
In this post, I was looking at static linking with no debugging option for all of them.

Collapse
kornelski profile image
Kornel

It doesn't give you any understanding of runtime size, because you've compiled in debug mode.

In debug mode compilers intentionally generate bloated code to be easy on debuggers, and add debug information. Precise debug information is generally a good thing, but it's very large.

For a comparison of runtime/stdlib overhead, you should compile in release mode, and then strip the executables. It would be wise to also use LTO (dead code elimination).

Collapse
aakatev profile image
Artem Author • Edited

Good point! I should have compared stripped versions too.