Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Very long compile time in large functions #215

Open
samuelbeek opened this issue May 23, 2016 · 18 comments
Open

Very long compile time in large functions #215

samuelbeek opened this issue May 23, 2016 · 18 comments

Comments

@samuelbeek
Copy link

Hi, using this tool, I found that a some of the larger constrain functions in my app take a really long time to compile, in the 500ms spectrum on a pretty new MacBook Pro. Do you know if there's specific things that cause these longer compile times? I'd love to contribute some improvements and can do some tests myself, but if you happen to know where to look that'd be great.

Thanks

@MPiccinato
Copy link

Just wanted to chime in and say I am seeing this also. Currently a huge chunk of my build time is spent in these methods. I use the same tool as @samuelbeek posted.

@samuelbeek
Copy link
Author

Both @MPiccinato and I dove into this and it is slowest when combining assignment and comparison operators. So for instance in a line like this one
view1.centerX == view.centerX + 10.

Anything we can do about that?

@samuelbeek
Copy link
Author

I've added a couple of functions to my project to replace the == operator in cartography. You can find them in this Gist (WIP). It slimmed down the compile time of most Cartography blocks to 30% of the original time, which are pretty impressive results.

@LucasVanDongen
Copy link

I'm seeing the same things. Compile times over 100ms for not overly complex stuff

Noticed one thing:

    constrain(self.contentView, self.titleLabel, self.contentLabel, self.newMessages) { (view: LayoutProxy, titleLabel: LayoutProxy, contentLabel: LayoutProxy, newMessages: LayoutProxy) in
        titleLabel.bottom == contentLabel.top
        
        titleRight = titleLabel.right == view.right - (intraCellSpacing + MessageCountIndicator.counterWidth) // Much faster
        contentLabel.right == titleLabel.right
        
        newMessages.centerY == view.centerY
        newMessages.right == view.right - intraCellSpacing
        newMessages.width == newMesagesWidth
        
        contentLabel.bottom == view.bottom - intraCellSpacing
        contentLabel.left == titleLabel.left
    }

vs

    constrain(self.contentView, self.titleLabel, self.contentLabel, self.newMessages) { (view: LayoutProxy, titleLabel: LayoutProxy, contentLabel: LayoutProxy, newMessages: LayoutProxy) in
        titleLabel.bottom == contentLabel.top
        
        titleRight = titleLabel.right == view.right - intraCellSpacing - MessageCountIndicator.counterWidth  // Slow version
        contentLabel.right == titleLabel.right
        
        newMessages.centerY == view.centerY
        newMessages.right == view.right - intraCellSpacing
        newMessages.width == newMesagesWidth
        
        contentLabel.bottom == view.bottom - intraCellSpacing
        contentLabel.left == titleLabel.left
    }

This shaved off 200ms from originally >300ms. Still not really great having them over 100ms but at lot better at least.

@CVertex
Copy link

CVertex commented Dec 22, 2016

Is it to do with type inference? Swift is still a dog with that

@Lascorbe
Copy link

Lascorbe commented Feb 28, 2017

I've come into this as well (having big compile times on all Cartography closures).

Looks like function overload could be the cause (constrain has various method overloads). I've been thinking how can we change it to solve the problem, but it is so good like it is right now...

Does someone think there's a good way of fixing it? Or should we just keep relying on thinking it'll get better on a future Xcode release?
I've thought of just having the constrain(_ view: [View] ...) one, and rename the other ones so it's clear which one is used, but I don't really like it :(

@ianyh
Copy link

ianyh commented Mar 6, 2017

I'm not sure it's the constrain overloads. I've tried reducing it to only the array call with no meaningful difference in compile time.

@ianyh
Copy link

ianyh commented Apr 20, 2017

For what it's worth, anecdotally this seems to be a lot faster for me nowadays.

@rvi
Copy link

rvi commented Apr 20, 2017

@ianyh What did you change to reduce the compile time?

@ianyh
Copy link

ianyh commented Apr 20, 2017

Nothing. Swift compiler changes seem to have improved the type inference, which is what I think was slowing it down.

@ianyh
Copy link

ianyh commented Apr 20, 2017

Again, this is somewhat anecdotal. I haven't done any thorough timing tests.

@rvi
Copy link

rvi commented Apr 20, 2017

Building my app after cleaning is more than 11min... Xcode 8.3.2 ?

@ianyh
Copy link

ianyh commented Apr 20, 2017

Yes. It's possible I've just adjusted to my capricious robot overlords. I'll do some more thorough timing when I get a chance.

@pedromcunha
Copy link

Any update on this issue? We have some large (30 line) constrain functions that are giving us 600-700ms compile time. Is there anything we can do to decrease this? Btw it looks like it hasn't been mentioned before but you can measure the compile time of functions by following this guide here: https://www.jessesquires.com/blog/measuring-compile-times-xcode9/?utm_campaign=iOS%2BDev%2BWeekly&utm_medium=web&utm_source=iOS_Dev_Weekly_Issue_320

@orta
Copy link
Collaborator

orta commented Oct 16, 2017

No updates, so you're welcome to take a look 👍

@s4cha
Copy link

s4cha commented Nov 20, 2017

Hi, reading this thread it seems very similar to an issue we had on Stevia a while ago, due to operator overloading, we're all in the same boat !
The way I understand it is that == is a common operator so the compiler has a hard time finding the right overload.
For instance, in our project replacing '-' operator by '--' made it easier on the compiler yielding faster compile times.
The bad news is this approach means touching the api :/
My best guess is to wait for the compiler to get better and better with each release as it seems to have improved over the past releases.
More details on the similar issue here: http://freshos.org/SteviaDocs/knownIssues/
Hope it helps :)

@acrookston
Copy link

acrookston commented Jun 15, 2018

I've added PR #293 as a potential solution. At Instacart we use Cartography heavily in one of applications and after migrating most of the code over to the new syntax the (clean) build time has been halved (from about 5 min to 2.5). All of our view constraint setups run in a few milliseconds where most were in the hundreds, if not thousands (worst case we had was 8800ms for one view).

Strongly recommend the core team looks over this issue and applies some (maybe not my) solution.

Feel free to use github "instacart/Cartography" "acr/custom-operator" (carthage) if you wish to get the improvements, unfortunately you must add the ~ prefix to all your ==, +, -, *, /, <= and >= operators, but hopefully we'll see a more permanent solution to this.

Thanks for a great library!

@jberkel
Copy link

jberkel commented Dec 21, 2018

It's difficult to find a satisfying solution without compromising the API.
As a workaround, one thing you can do is to help the type checker:

- label.baseline == otherLabel.firstBaseline + 10
+ let _:NSLayoutConstraint = label.baseline == otherLabel.firstBaseline + 10 as Expression<Edge>

Less readable but improves compile times considerably. If it looks like the compiler performance problems won't be addressed (soonish) then a new API is probably in order.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests