5 ms·
I've noticed that the compiler (both real-time analysis and actual compiling) gets sluggish and unreliable over time when a project grows. I think I've found th
by dep_b 10y ago
I've noticed that the compiler (both real-time analysis and actual compiling) gets sluggish and unreliable over time when a project grows. I think I've found the source of the problem and unfortunately for people in large code bases it does take a bit of rewriting to get it back into shape.
Since the language is very strictly typed yet allows for a loose syntax, the compiler needs to guess which type you are actually using. For example the type Any? always works but perhaps you are declaring it like a dictionary that always uses a string as a key? It doesn't know until it analyzes all keys and sees that you're indeed always using a string as an index. Put one Int in the end of a long list and it breaks.
Now something like this doesn't hurt:
let indexOfTab = 4
Because the compiler sees you're trying to put an int in a constant.
But this is a bit more difficult:
let tabDict = [ /* long list of declarations here */ ]
let indexOfTab = tabDict.first(where: { key, value in value == "contacts" })?.key ?? 0
First it needs to know if that tabDict indeed would have only Ints or similar values as keys and only strings as values because they would now need to match what happens in the filter.
This makes the complexity of the code to analyze explode in a way that if your code consists of many of these things you all of the sudden find your computer go to a crawl.
The alternative however is a bit more ugly (I could use a bad word to describe it, like: "Java"):
let tabDict: [Int: String] = [ /* long list of declarations here */ ]
let tabWithContact: [Int: String] = tabDict.first(where: { key, value in value == "contacts" })
let indexOfTab: Int = tabWithContact?.key ?? 0
(bear with me, this code is not checked in Xcode, just a hasty example)
Now step by step the compiler does not have to guess anymore, if the first line doesn't compile (because for example you've added a string as a key) it just won't compile. Same goes for the filter function, if you treat the types wrong inside the filter block. Also not too much to guess in the third line, it will never guess what type the key is let alone compile if you would declare indexOfTab as a String.
What I would like to see is:
* A tool that can actually show the points where your code is slowing down the compiler a lot
* A tool that proposes you to split the declarations up for faster execution just like you can automate much of the changes after upgrading to a new version of Swift
All I do now is guessing and adding more code to get performance back to acceptable levels.
- timjver 10y agoNot disagreeing with anything that you're saying, except that dictionaries are declared `[Key: Value]` and not `[Key, Value]`. By the way, rather than using `.filter { ... }.first`, you should really use `.first(where: { ... })` instead. `filter` will iterate the entire sequence, while `first(where:)` stops after it finds a match.
- dep_b 10y agoAll true! Let me fix it. I remember the "where" approach not completely working like I expected it, didn't dare to put it in without checking :)
- seanmcdirmid 10y agoThis sounds bad, what type inference algorithm is Swift using? If they are computing some kind of least upper bound, I'm not sure why it would get so slow.
- dep_b 10y agoThe difference between JS and Swift is that Swift compiles everything with static types. So JS just plods along and does one of it's funky things with types when encountering the next instruction, but Swift actually needs hard types to be able to compile and run at all. So you need to provide them, or it figures them out by itself. There used to be this famous error about "too complex" statements. They still exist but got a lot less: "swift expression was too complex to be solved" http://stackoverflow.com/questions/29707622/bizarre-swift-compiler-error-expression-too-complex-on-a-string-concatenation http://stackoverflow.com/questions/29707622/bizarre-swift-co... Also check the second answer, it's actually the best.
- seanmcdirmid 10y agoI'm pretty well versed in static vs. dynamic typing. In that example, they aren't inferring through a generic + type, but are rather doing it in a brute force manner, forking the world each time they have to consider an alternative. I guess this pitfall is why experienced type system designers make the big bucks.