Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Rust compile a simple program 5-10 times slower than gcc/clang?

Tags:

rust

Follow-up to Rust minimal compiled program size.

rustc hello.rs > 600 ms 

Why does rustc compile a simple Hello World 5-10 times slower than gcc/clang?

Rust uses LLVM so it should be on par with clang. Anyway we are talking about a program that has only three lines of code.

rustc hello.rs -C opt-level=0 -C prefer-dynamic > 400 ms  gcc hello.c > 60 ms  clang hello.c > 110 ms 
like image 308
exebook Avatar asked May 21 '16 11:05

exebook


People also ask

Why does Rust compile time slowly?

That is because the languages are different and choose different tradeoffs. The tradeoffs might make a language inapplicable in your domain. Rust has always been marketed as a "systems programming language". C++ is Rust's closes competitor in this domain space and it suffers from terribly slow compiling as well.

Is Rust slow to compile?

It is true that Rust is slow to compile in a rather fundamental way. It picked “slow compiler” in the generic dilemma, and its overall philosophy prioritizes runtime over compile time (an excellent series of posts about that: 1, 2, 3, 4).

Why is Rust slower than C?

Rust without safety checks The resulting transpiled code forwards a packet in only 91 cycles while executing 121 instructions, that's faster than the original code. It holds true even when the original code is compiled with clang and the same LLVM version.

Why does Rust use LLVM?

rustc uses LLVM to generate code. LLVM can generate very fast code, but it comes at a cost. LLVM is a very big system. In fact, LLVM code makes up the majority of the Rust codebase.


1 Answers

First of all, I don't think it's very meaningful to compare the compile time of two extremely simple programs and expect the result to be representative of compilation times between two languages more generally.

That said, I do expect that Rust, being a language that provides a level of abstraction much more common to higher level languages with little to no runtime performance cost, would have to pay for that to some extent at compile time.

This excerpt is taken from the Rust FAQ:

Rust compilation seems slow. Why is that?

Code translation and optimizations. Rust provides high level abstractions that compile down into efficient machine code, and those translations take time to run, especially when optimizing.

But Rust’s compilation time is not as bad as it may seem, and there is reason to believe it will improve. When comparing projects of similar size between C++ and Rust, compilation time of the entire project is generally believed to be comparable. The common perception that Rust compilation is slow is in large part due to the differences in the compilation model between C++ and Rust: C++’s compilation unit is the file, while Rust’s is the crate, composed of many files. Thus, during development, modifying a single C++ file can result in much less recompilation than in Rust. There is a major effort underway to refactor the compiler to introduce incremental compilation, which will provide Rust the compile time benefits of C++’s model.

Aside from the compilation model, there are several other aspects of Rust’s language design and compiler implementation that affect compile-time performance.

First, Rust has a moderately-complex type system, and must spend a non-negligible amount of compile time enforcing the constraints that make Rust safe at runtime.

Secondly, the Rust compiler suffers from long-standing technical debt, and notably generates poor-quality LLVM IR which LLVM must spend time “fixing”. There is hope that future MIR-based optimization and translation passes will ease the burden the Rust compiler places on LLVM.

Thirdly, Rust’s use of LLVM for code generation is a double-edged sword: while it enables Rust to have world-class runtime performance, LLVM is a large framework that is not focused on compile-time performance, particularly when working with poor-quality inputs.

Finally, while Rust’s preferred strategy of monomorphising generics (ala C++) produces fast code, it demands that significantly more code be generated than other translation strategies. Rust programmers can use trait objects to trade away this code bloat by using dynamic dispatch instead.

like image 89
TheInnerLight Avatar answered Sep 22 '22 13:09

TheInnerLight