Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Could you provide a documentation on the compiler model of Swift, and why it would be slower? How can that model be compared to clang's c++ compiler model?


The model for Swift is for the compiler to do a lot of work.

Doing a lot of work takes more time than doing less work.

There was an interview/article a while back that explained this for C++/D, I think it might have even been by Walter Bright himself, that explained this really well. Sadly, I can't find it right now.

In essence, C++ is predicated on the compiler being able to see through any abstractions you might have provided at compile time, in order to be able to optimize that away. That means you effectively lose separate compilation, because the compiler has to look at the implementation of dependencies, not just at their interfaces. Transitively.

So C++ is a lot slower to compile than C/Objective-C, and Swift is very similar, it just doubles down on that model. With this model it doesn't come as a surprise that compiling everything at once is often massively quicker than compiling single source files, the "whole module optimization without optimization" thing.

I also think there's at least some polynomial factor involved here, so as your projects get bigger, per-file compile times get significantly slower.

C and Objective-C really take separate compilation to heart, so you don't run into nearly the same problems (though: header files :-( ). Go is a more modern take on this, compile times are legendary.

In addition to that, Swift leans extremely heavily on the optimizer to get common constructs to execute in reasonable time, rather than 100x or more slower than you'd expect. That also costs. A lot. tcc doesn't really optimize much, it's a good example of how fast a C compile can go. (I clocked it at several hundred thousand lines of code per second or more, for comparison, numbers from a Swift project were 60 lines of code per second).

And last not least there's pretty wild forward/backward type inference, which will happily go exponential. For example, let's look at the following code:

   let a:[Int] = [1] + [2] + [3] + [4] + [5] + [6]
This actually used to fail with "expression too complex", nowadays it compiles in 26 seconds on my machine, and adding one more integer array gets it to fail again, after 59 seconds. Hmmm...


Thanks for the write up. There are massive benefits to having a simple language.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: