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

Improve compilation time of icrate #311

Closed
madsmtm opened this issue Dec 23, 2022 · 9 comments · Fixed by #328
Closed

Improve compilation time of icrate #311

madsmtm opened this issue Dec 23, 2022 · 9 comments · Fixed by #328
Labels
A-framework Affects the framework crates and the translator for them help wanted Extra attention is needed
Milestone

Comments

@madsmtm
Copy link
Owner

madsmtm commented Dec 23, 2022

Probably by making everything hidden behind selective cargo features like Foundation_NSMutableArray (which would transitively enable Foundation_NSArray and Foundation_NSObject).

@madsmtm madsmtm added the A-framework Affects the framework crates and the translator for them label Dec 23, 2022
@madsmtm
Copy link
Owner Author

madsmtm commented Dec 24, 2022

So far I've determined that the compilation time has increased quite a lot since I last looked at it - it's now at ~48 seconds.

Further investigation shows that the extern_methods! declaration is the most time-consuming (accounting for ~80%) (not so very surprising). But even if I change things so that we manually output MessageReceiver::send_message (and equivalent for msg_send_id!), the time only drops by a small amount (~45s), so the increased time comes from #198 maybe?

@madsmtm
Copy link
Owner Author

madsmtm commented Dec 24, 2022

Indeed, doing [profile.dev] debug-assertions = false immediately cuts the time down to ~33s

@madsmtm
Copy link
Owner Author

madsmtm commented Dec 24, 2022

Noting down -Ztime-passes and -Zself-profile for my own future reference

@silvanshade
Copy link
Contributor

silvanshade commented Jan 9, 2023

So far I've determined that the compilation time has increased quite a lot since I last looked at it - it's now at ~48 seconds.

I've been working on #327, trying to get to a point where the WebKit bindings are usable, and so far this seems to be one of the bigger issues I'm facing. After adding the method skip directives from that PR to the translation config, compilation doesn't immediately error anymore (more on that though) but compilation seems to take a very long time. I waited several minutes a few different times and never saw it finish.

I've tried manually including only the definitions needed from the generated output, and I'm seeing some more errors now (which I'm fixing), so maybe somehow compilation times will get better if I track down the remaining issues.

However, I'm thinking the approach you mention, i.e. feature Foundation_NSMutableArray transitively enables features Foundation_NSArray and Foundation_NSObject, may not make a significant impact unless it's also possible to exclude most methods. Although maybe you have plans to account for this?

For example, just trying to include enough of the generated output to import WKWebView has me having to go through and import so much other unused stuff that it's probably going to end up pulling in almost all of the WebKit module.

Maybe it would work to follow what web_sys crate does. There the features are usually not transitive, or not deeply transitive at least, but instead, if you have some object A with a method f that mentions a type B, then in order to use A::f, you must enable Feature_A and Feature_B.

The downside is that it's slightly more tedious to enable the features you need, but the upside is you include far less code during compilation so it should be a lot faster overall. It should also be easier to generate the feature gating since you don't need to track dependencies beyond the types mentioned in the selectors.

@madsmtm
Copy link
Owner Author

madsmtm commented Jan 9, 2023

This issue has high priority for me as well, since it's a blocker for me using icrate in winit. I'm working on it in #328.

However, I'm thinking the approach you mention, i.e. feature Foundation_NSMutableArray transitively enables features Foundation_NSArray and Foundation_NSObject, may not make a significant impact unless it's also possible to exclude most methods. Although maybe you have plans to account for this?

For example, just trying to include enough of the generated output to import WKWebView has me having to go through and import so much other unused stuff that it's probably going to end up pulling in almost all of the WebKit module.

Maybe it would work to follow what web_sys crate does. There the features are usually not transitive, or not deeply transitive at least, but instead, if you have some object A with a method f that mentions a type B, then in order to use A::f, you must enable Feature_A and Feature_B.

I think my plan was to do as you describe, both for methods and for functions.

Unsure how typedefs, structs and enums should work, perhaps something like "find all methods that references this struct/typedef/enum, and then all the classes that define those methods, and from that all the features"? Or maybe use Swift data to see which class something belongs to (e.g. NSFontWeight is NSFont.Weight in Swift, so we could probably gate that behind "AppKit_NSFont")?
But that can probably be handled later.

The downside is that it's slightly more tedious to enable the features you need, ...

True, but probably only rarely, since if you're using a method that takes some class, you've likely already imported that class in you code elsewhere.

maybe somehow compilation times will get better if I track down the remaining issues

I've also found that if rustc encounters an error, it will take a lot more time to compile, probably due to a combination of backtracking taking time, and that these are less-optimized code paths - there's probably a flag to make rustc error out the instant it finds an issue with your code, instead of trying to deduplicate errors and such, but I'm not aware of it.

@madsmtm
Copy link
Owner Author

madsmtm commented Jan 11, 2023

Perhaps -Ztreat-err-as-bug=1 can help with finding errors quicker? Though it doesn't really seems like it helps much :/

@silvanshade
Copy link
Contributor

Perhaps -Ztreat-err-as-bug=1 can help with finding errors quicker? Though it doesn't really seems like it helps much :/

Thanks for the suggestion. I saw that earlier and tried it but didn't have much luck initially. But I tried again and have been able to start tracking down more of the errors for translating WebKit.framework. It turns out it will also depend on the JavaScriptCore and Security frameworks for a full translation, but I think I can manage to skip most of the involved methods for now.

@madsmtm
Copy link
Owner Author

madsmtm commented Jan 11, 2023

Note that I would not mind having either of those, though header-translator would probably need to get much better at doing CoreFoundation-like frameworks first. So yeah, skipping the methods that involve those frameworks seem like a good idea to start with.

@madsmtm madsmtm added the help wanted Extra attention is needed label Jan 11, 2023
@madsmtm madsmtm added this to the icrate v0.1.0 milestone Jan 27, 2023
@madsmtm
Copy link
Owner Author

madsmtm commented May 26, 2023

In #448 I'm considering using file names / module names as the basis for feature names, instead of class names.

This will probably mean we won't transitively enable features any more, like you suggested here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-framework Affects the framework crates and the translator for them help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants