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

Long compile times #418

Closed
mohan-win opened this issue Oct 12, 2016 · 18 comments
Closed

Long compile times #418

mohan-win opened this issue Oct 12, 2016 · 18 comments

Comments

@mohan-win
Copy link

I'm using Argo in production app, and I can see that the Swift compile time takes a lot of time in my project. Wondering if this is because of Argo & Argo based models which use a lot of generic code ? Please let me know if you have done any bench marking around this.

Argo Version

Argo 3.1

Dependency Manager

Carthage

@tonyd256
Copy link
Contributor

Most likely this is due to a large model that has some complex or large quantity of Argo decoding going on. Argo usually speeds up with smaller models or simpler decoding setups. If you paste some of your bigger models here we could help advise where a slowdown maybe occurring.

@mohan-win
Copy link
Author

@tonyd256 Thanks for replying. I don't have single large model in the app, however I've around 20 smaller models with max 15 properties. So I hope this won't hurt the compile time ?

I tried to measure the compile time with "-Xfrontend -debug-time-function-bodies" and I don't see much compilation times reported Argo based models. I hope the above flag would have exposed if argo based models are at fault ?

@tonyd256
Copy link
Contributor

15 properties is a large enough model to slow down compile time for sure. I'd suggest trying to break up anything around 10-12 properties into smaller models. You could also try making it easier for the compiler by adding an explicit type to each line like so: <*> j <| "name" as Decoded<String> (might need parens)

@mohan-win
Copy link
Author

@tonyd256, thanks for the suggestions. Will do that for the larger models!

@dalu93
Copy link

dalu93 commented Oct 19, 2016

FYI, @tonyd256 solution works quite fine as temporary fix. One of our project's model was compiling in 11568.x ms and now, with the explicit type, it takes only 26.x ms

@tonyd256
Copy link
Contributor

@dalu93 Great to hear! Unfortunately, I think this is a limitation of the Swift compiler and there isn't much Argo can do to lighten the load without sacrificing what it is. Closing this for now, but feel free to continue commenting or create a new issue for anything new!

@dalu93
Copy link

dalu93 commented Nov 15, 2016

Hi @tonyd256, the workaround is not working anymore after upgrading to Swift 3. The error I get is:

No '<|' candidates produce the expected contextual result type 'Decoded<_>'

The configuration I have is:

Argo 4.1.0
Curry 3.0.0
Runes 4.0.1

Is there a way to apply the same behavior? I'm getting again long compile times unfortunately

@gfontenot
Copy link
Collaborator

@dalu93 you might need to add some parens around the j <| "foo" part of the expression. This is due to precedence changes we needed to make alongside Swift 3

@zhijunsheng
Copy link

I started trying Argo today. Unfortunately with a very small model object User, the compiler either spent painfully long time or gave me "Expression was too complex to be solved in reasonable time". If I commented out some fields and left 4 or 5 in User struct, the compiling time is a few seconds, which is OK. So I have big concern whether Argo is ready for production.

@jshier
Copy link
Contributor

jshier commented Apr 27, 2017

There are a few different ways to mitigate the Swift compiler's performance issues with Argo, which you can read about here. And it's best to open an issue and show your code if you have performance issues you can't solve yourself. I've shipped two apps now that use Argo as their JSON decoding framework.

@gfontenot
Copy link
Collaborator

@zhijunsheng Like @jshier said, if you could open a new issue with more sample code that'd be helpful for us. We're shipping Argo with dozens of client applications, and it's also included in other large scale apps without seeing the compiler issues you're describing.

@zhijunsheng
Copy link

Thanks for your quick responses! Now I'm upgrading Xcode from 8.3.1 to Xcode 8.3.2 since it said "improves performance". I'll try more and may report Argo performance issues if I do find some. BTW I already read the page jshier suggested and, what I just tried is very simple. A User struct with 10 fields of type String or Bool, the compiler took about 1 minute to finish; if I commented out 5 or 6 fields, the time was about a few seconds.

@donaldsheng
Copy link

I just tested on another computer with Xcode 8.3.2 (Curry at "v3.0.0", Runes at "v4.0.1", Argo at "v4.1.2"). The result is basically same. If I comment out the last 3 fields, the compiling time is less than 10 seconds; otherwise it is more than 20 seconds.

struct User {
    let id: Int
    let firstName: String?
    let lastName: String?
    let jobTitle: String?
    let neighbourhood: String?
    let avatarURL: String?
    let useFacebookPicture: Bool?
    let isLead: Bool?
    let isFullyVerified: Bool?
}

extension User: Decodable {
    static func decode(_ j: JSON) -> Decoded<User> {
        return curry(User.init)
            <^> j <| "id"
            <*> j <|? "first_name"
            <*> j <|? "last_name"
            <*> j <|? "job_title"
            <*> j <|? "neighbourhood"
            <*> j <|? "avatar_url"
            <*> j <|? "use_facebook_picture"
            <*> j <|? "is_lead"
            <*> j <|? "is_fully_verified"
    }
}

@Arcovv
Copy link

Arcovv commented Apr 28, 2017

@donaldsheng One can try to solve the following:

extension User: Decodable {
    static func decode(_ j: JSON) -> Decoded<User> {
        let tmp1 = curry(User.init)
            <^> j <| "id"
            <*> j <|? "first_name"
            <*> j <|? "last_name"
        let tmp2 = tmp1
            <*> j <|? "job_title"
            <*> j <|? "neighbourhood"
            <*> j <|? "avatar_url"
        return tmp2 
            <*> j <|? "use_facebook_picture"
            <*> j <|? "is_lead"
            <*> j <|? "is_fully_verified"
    }
}

This writing can improve the speed of Xcode compilation

@zhijunsheng
Copy link

@Arcovv That did the trick! Now it's super fast. Thanks a lot.

@jshier
Copy link
Contributor

jshier commented Apr 28, 2017

Just separating out the curry call should be a substantial improvement by itself.

@zhijunsheng
Copy link

zhijunsheng commented Apr 28, 2017

Thanks for all the hard work and help! 👍
BTW this "separating out the curry call" trick should be put together with "Hello World" sample, obviously. :-)

@wongzigii
Copy link

Thanks for this hack! I decrease the project compiler time from 5 mins to 15 seconds!. Life saver. 🎉

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

9 participants