Recently I have been working on one of my side project in Swift. Originally, everything looked fine, but not sure starting from when, the whole compilation process started to be slowed down a lot from 20s to more than 5 mins!!
Originally I was thinking it’s mainly caused by some of my 3rd-party libraries because I did install some new ones during that period. So as an engineer, I started to bisect and see what’s going on. But after uninstalling / reinstalling those libraries, things are not going well though.
Ok so it looks like this way is not working and not the root cause, so what’s next ? After thinking a while, I started to check codes line by line and see what’s the most suspicious part that can cause the problem. TBH, there was no any piece of codes looking suspicious to me… Ok no ways to go again, the only thing I could do is to narrow down variables and started to comment out methods from entry point.
After a while, boooooom, I finally found the part which would cause the problem !!!!
What the hell, it’s all about +
!! Because I mainly work things in JavaScript, it’s really not intuitive to me that this can be the problem! After googling around, here comes some comments about this problem :
It has to do with type inference. Each time you use the
+
operator, Swift has to search through all of the possible overloads for+
and infer which version of+
you are using. I counted just under 30 overloads for the+
operator. That’s a lot of possibilities, and when you chain 4 or 5+
operations together and ask the compiler to infer all of the arguments, you are asking a lot more than it might appear at first glance.That inference can get complicated – for example, if you add a
UInt8
and anInt
using+
, the output will be anInt
, but there’s some work that goes into evaluating the rules for mixing types with operators.And when you are using literals, like the
String
literals in your example, the compiler doing the work of converting theString
literal to aString
, and then doing the work of infering the argument and return types for the+
operator, etc.If an expression is sufficiently complex – i.e., it requires the compiler to make too many inferences about the arguments and the operators – it quits and tells you that it quit.
I think I am too familiar with languages like JavaScript, so all the details like this are all hidden and not exposed to us. No matter how, it’s still surprising though. Hope in Swift 4, this kind of basic operations like Array concat can be optimized and boosted up.