Anchorage
Anchorage copied to clipboard
Type-checking Performance
We're using anchorage in our app and have something akin to this in our xcconfig:
OTHER_SWIFT_FLAGS = -Xfrontend -warn-long-function-bodies=400 -Xfrontend -warn-long-expression-type-checking=400
We compile Anchorage from source due to needing a static lib and Anchorage code as well as our app are consistently causing warnings.
For Anchorage, it's the performInBatch(closure:)
call in func constraints(forAnchors:, firstConstant c1:, secondConstant:, priority:, builder:)
(Internal.swift
).
In our app, functions that have numerous calls to Anchorage.batch(active:closure:)
ini the same function tends to also fail this check.
Thanks for the report. I’m curious whether you’re using the batching for particular performance reasons, or to get disabled constraints, or just as a catch-all? We usually don’t use it unless we have a performance hotspot.
Also, it would be cool to revisit batch using function builders!
Hi!
Somehow related topic. The use of anchorage operators also decreases type inference performance. A simple method setting up 4 views with approximately 15 anchors takes ~140ms to type check.
Example:
Does anybody has clues what is the cause and how to fix it?
Thanks!
So I've given it some thought and my best guess is that the type checker is checking of all possible ways to resolve X == Y
, X == Y + 1
and similar expressions. As there are a lot of ==
operators defined, that takes a lot of time.
My best guess is that the type checking performance would increase if there were some other operators than ==
, for example <==>
.
I don't have time now to test my hypothesis, but I'm planning on doing that some time in the future
Operator overloads are the slowest to type-check, and have (IIRC) exponential time complexity. It would likely be a lot faster to avoid operators and use named functions instead.
@chrisballinger .. which kills all the beauty of using anchorage in the first place :)
skate to where the operator overload type checking performance puck is going to be 😉⛸🏒
Its really nice tool, but build time is killing me ;/ How about adding set of methods that can be used in parallel with operators?
i'm seeing 3 major advantages of this solution:
- this library won't be replaced in existing projects
- it won't discourage new users if they will know, that if the project grows, they won't have to rewrite entire code for auto layout
- having methods in parallel with operators, gives possibility of auto-migration from == to methods with just couple lines of code
I could definitely see the advantage of splitting things out so that the operators become sugar over a set of methods. Anchorage provides so many niceties, like setting translates
correctly and pinning various edges and centers, and I can see the appeal of wanting that niceness without incurring the operator overloading performance hit.
All that said, I'm even more interested in finding out what can be done to improve compilation time. Now that we support SPM, I might look into submitting this repo to the various Swift compatibility suites and performance benchmarks.
Cartography has a similar issue with overloaded operators increasing compile times. There's a PR to add custom operators replacing the overloaded operators that significantly decreases compile times: https://github.com/robb/Cartography/pull/293
It would be nice for this to be fixed in Swift itself but I don't know if that's possible
A nice first step would be to add Anchorage to the Swift Source Compatibility Test Suite: https://github.com/Rightpoint/Anchorage/issues/40