Rightpoint / Anchorage

A collection of operators and utilities that simplify iOS layout code.
MIT License
627 stars 46 forks source link

Type-checking Performance #83

Open vlozko opened 4 years ago

vlozko commented 4 years ago

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.

ZevEisenberg commented 4 years ago

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!

ULazdins commented 4 years ago

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: ChannelListThumbnailView_swift

Does anybody has clues what is the cause and how to fix it?

Thanks!

ULazdins commented 4 years ago

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

chrisballinger commented 4 years ago

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.

ULazdins commented 4 years ago

@chrisballinger .. which kills all the beauty of using anchorage in the first place :)

ZevEisenberg commented 4 years ago

skate to where the operator overload type checking performance puck is going to be 😉⛸🏒

Przemyslaw-Wosko commented 4 years ago

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: 1) this library won't be replaced in existing projects 2) 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 3) having methods in parallel with operators, gives possibility of auto-migration from == to methods with just couple lines of code

ZevEisenberg commented 4 years ago

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.

jayrhynas commented 4 years ago

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

ZevEisenberg commented 4 years ago

A nice first step would be to add Anchorage to the Swift Source Compatibility Test Suite: https://github.com/Rightpoint/Anchorage/issues/40