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
[SR-2901] Synthesized properties type-checked once per file in the target/module #45495
Comments
Comment by Ben A (JIRA) Based on Mark's comments here, there may be some cases in which |
I think you mean "type-checked" rather than "parsed". |
As part of chasing this down, someone could consider getting accessors to print more nicely in the output of |
Comment by Ben A (JIRA) What kind of additional information would be useful? The SourceLoc is already logged. I should have mentioned that I omitted it because I didn't think that info would be useful in aggregate (i.e. each line has a different SourceLoc, and knowing that for my project would probably just be noise here). Were you looking for something to the effect of: "these are mostly properties with access level <level>", "are mostly of type <t>", etc.? Those are all things I can easily collect in my script, since I have the SourceLoc available, while I file another ticket to add extra, needed information for the log. |
Oh, not for us, or for any real analysis, just to make the output a little prettier. "getter for 'foo'" instead of just "get". |
Comment by Ben A (JIRA) Ah gotcha. Filed SR-2910 |
Comment by Ben A (JIRA) Confirmed that this only happens when you pass the |
That makes absolutely no sense. Every module has a name; it's just that that name is sometimes inferred and sometimes explicit. How did you confirm this? |
Comment by Ben A (JIRA) Oh your right. I thought the only difference between the two commands I was running was the test_file1.swift: class B {
let a: A
init() {
a = A(s: "test")
}
} test_file2.swift: struct A {
let s: String
} Here are the 2 similar commands and their varying outputs: 1.
2.
In 2, |
Order of files sounds much more plausible (and still a problem, of course). Thanks, Ben. |
Comment by Ben A (JIRA) Sorry to clarify, I meant that file order here has no impact. You can reorder the files in either command and get the same results, in terms of number of times each method is type-checked. |
Comment by Ben A (JIRA) That still leaves the question: what is different about these two commands that would cause one to type-check properties fewer times? |
Comment by Graydon Hoare (JIRA) The first invocation is passing (To be clear: there looks to be some redundant work in the typechecker, in terms of checking synthesized get/set bodies merely referenced from another file, but that redundant work is not quite as quadratic as it might seem from this example; it's only checking each synthesized body once per frontend run. I am currently investigating ways to limit this.) |
Comment by Steven Sheldon (JIRA) I think we were seeing the synthesized bodies checked once per file, on the mailing list Ben mentioned:
Does Xcode use a frontend job per Swift file? |
Ah, wow, I completely missed that. Yes, a non-whole-module build uses one frontend process per .swift file. (Additionally, calling the frontend directly is unsupported.) @rudkx has actually already fixed some of this redundant work, and as graydon (JIRA User) said he's looking into more cases of it. |
Comment by Ben A (JIRA) Ah okay that makes sense. Thanks! |
Comment by Graydon Hoare (JIRA) A PR that seems to fix it is here: #5588 |
Comment by Graydon Hoare (JIRA) Merged 9351843 |
Comment by Ben A (JIRA) Awesome![]( Excited for the upcoming snapshot) |
Environment
macOS Sierra
Swift 3.0
Additional Detail from JIRA
md5: f12720121b8f3fdd3662fb338eed86eb
Issue Description:
After some discussion with Mark Lacey, I found that in our project synthesized properties with the following signatures (as logged using the -debug-time-function-bodies debug flag) are type-checked once per file in our project (607 files in the project x 2521 generated setters/getters = ~1.5 million "type-checks"):
I got these signatures by getting lines from -debug-time-function-bodies output like this for example:
, parsing the log with a script, and compiling the set of all signatures that were logged the same number of times as there are files in the target in question.
This was done using a custom toolchain built off of
swift-3.0-branch
, but I got similar results using the Swift 3.0 that comes with Xcode 8.0 (App Store version).I used a custom toolchain here, so that I could increase the number of decimal places logged by -debug-time-function-bodies. By doing that, I could then determine that fixing this bug would save ~40 seconds when building our main target. Otherwise, many of these lines show up as the function taking 0.0ms to type-check, since the time elapsed is less than 0.1ms but adds up over time. I'll put up a PR to add this soon.
Update: Link to PR
The text was updated successfully, but these errors were encountered: