7 ms·
What I've heard is that the output that the Rust compiler gives to LLVM is much more complex than it needs be, and optimising this is the simplest way to reduce
by noelwelsh 9y ago
What I've heard is that the output that the Rust compiler gives to LLVM is much more complex than it needs be, and optimising this is the simplest way to reduce the time spent in LLVM. This seems plausible to me as there aren't many complaints that other compilers using LLVM are slow.
- arghwhat 9y agoThat depends on what you are comparing to. Both GCC and Clang are very slow compared to, say, the Go standard compiler. However, comparing compilation speed across languages and compiler implementations is a bit difficult.
- banachtarski 9y agoThey also do a lot more work.
- arghwhat 9y agoThat really depends on your definition of "work". They certainly spend more clock cycles and produce more heat. They might have some more comprehensive optimization passes eating extensive cycles, but even rustc debug builds are extremely slow in comparison to the Go standard compiler.
- jerf 9y agoI'm not sure what a definition of "work" would look like where the Go compiler is doing as much "work" as the Rust compiler, but I expect it would be extraordinarily contrived. Go deliberately prioritizes compiler speed, and definitely skips complex optimizations that Rust or LLVM do, and Go is just generally simpler to compile, because the compiler will do nothing even remotely resembling the borrow checker, nor does it have complex types, and so on. (One of my benchmarks for "Go has really made it" is when someone starts selling an optimized Go compiler that does the expensive optimizations. You could still ideally use the standard Go compiler to develop, but then you'd test and deploy with the slow optimized compiler.)
- foldr 9y ago>Go deliberately prioritizes compiler speed, and definitely skips complex optimizations that Rust or LLVM do As the OP pointed out, Rust debug builds are still much slower than Go builds, so lack of optimizations can't be a big part of the story. The simplicity of the language and the deliberate design of the compiler for speed seem to be the main factors.
- jerf 9y agoYou should have added the next bit after where you cut the quote off, which was "and Go is just generally simpler to compile, because the compiler will do nothing even remotely resembling the borrow checker, nor does it have complex types, and so on." I'm not claiming this is true by any means, but it wouldn't surprise me that much that merely the work to tell if a bit of Rust code in, say, Servo, is legal Rust in the presence of a rich type system and the borrow checker and all the other such things going on is more work than it would be to compile the roughly-equivalent Go module entirely. Compared to Rust, Go does not so much "cut corners" as cut entire dimensions out of the picture, and then cut some more corners for good measure.
- pcwalton 9y agoThe Go compiler cuts out nearly all the optimization that LLVM does.
- foldr 9y agoI cut it off because I was only disagreeing with the bit before the 'and'. Indeed, Rust is a more complex language and it is not surprising that it would take longer to compile. Although, as another poster pointed out, Go code also compiles much faster than plain C code (with gcc or clang), and C is of a similar order of complexity to Go.
- gameswithgo 9y agogccgo
- 9y ago
- coldtea 9y ago>They might have some more comprehensive optimization passes eating extensive cycles, but even rustc debug builds are extremely slow in comparison to the Go standard compiler. Work is not just the optimization. Having Rust track lifetimes and warn about ownership bugs, races, etc, is also productive work for the compiler -- and happens during the debug builds too.
- arghwhat 9y agoThe post mentions that the majority of the execution occurs in LLVM, especially for optimized builds. In other words, anything Rust related has to be a smaller part of the compile time. I stated in my parent comment that cross-language/cross-compiler comparisons is tricky exactly because of the vast differences in both frontends (lifetime tracking, warning generation) and backends (code generation, optimization). So yes, I know there are different amounts of work related with different languages. However, I believe the compile time differences significantly outweigh the compile time differences.
- coldtea 9y ago>The post mentions that the majority of the execution occurs in LLVM, especially for optimized builds. In other words, anything Rust related has to be a smaller part of the compile time. A, true, by the time it hits LLVM Rust's lifetime's analysis has already happened...
- arghwhat 9y agoI'm a retard. > However, I believe the compile time differences significantly outweigh the compile time differences. I meant to say "the compile time differences are significantly greater than the language-independent differences".
- noelwelsh 9y agoRight, but compilation performance is not a race in which you have to be first, but a minimum threshold that you must meet. Compilation just has to be fast enough that it doesn't annoy developers most of the time. Once you achieve that they'll mostly stop complaining. I believe Clang et al are fast enough. (This is true for performance and optimisation is general: fast enough is good enough.)
- arghwhat 9y agoCompiling larger projects, I certainly do not feel that Clang et.al. are fast enough. It takes minutes to compile stuff at work with 32 Xeon threads powering through at full load. Once it takes seconds, we can talk about "fast enough".
- noelwelsh 9y agoTry using Scala :) Is that minutes for every compile, or for an (infrequent) full compile?
- pdpi 9y agoNot the commenter you're responding to, but at my previous place I dealt with compile times of around 20 minutes from scratch, and 1-2 minutes incremental using Clang/LLVM, on a 20ish physical core Xeon with 128ish gigs of RAM.
- iClaudiusX 9y agoNot to pick on you or the parent comment, but this is a such a common mistake that it's worth correcting. "Clang" is a thing not a person, therefore it's appropriate to use et cetera, not et alii. The former is for things, the latter for people (usually limited to authors of academic papers).
- coldtea 9y ago>Both GCC and Clang are very slow compared to, say, the Go standard compiler. Well, the Go standard compiler doesn't do much.
- brighteyes 9y ago> there aren't many complaints that other compilers using LLVM are slow. Practically every VM that tried to use LLVM as a JIT gave up as it was too slow. WebKit eventually abandoned their LLVM backend and wrote their own, B3. JITs are of course a specialized use case, but there are also known issues with compilation speed in LLVM. For example, LLVM is single-threaded, so compiling a single very large compilation module can be much slower than it needs to be - and this is an issue hit by Rust due to how crates are designed. But you are also very correct that Rust is generating overly-complex LLVM IR for LLVM to compile, which is another problem there. Also worth noting that while once clang beat gcc in compilation speed, as clang's optimizations have caught up to gcc the difference has vanished, and on many benchmarks today gcc compiles more quickly.
- chrisseaton 9y ago> Practically every VM that tried to use LLVM as a JIT gave up as it was too slow. And it doesn't even seem to work effectively as a target for JIT. It can do the machine code emitting part of a JIT well, but that wasn't really the problem and it doesn't seem to work well at the real problem of optimising code for a high-level language. You need to optimise yourself, by writing basically your own compiler pipeline, before emitting LLVM. See for example the Rubinius implementation of Ruby.