-
-
Notifications
You must be signed in to change notification settings - Fork 392
Compute Partial module graph fingerprints #4594
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
Conversation
Thank you for working on that topic. I applied the patch and did not observe much improvement in my work codebase (e.g. any added I will have a look a bit later during the day with the "simple" examples that I had provided in #4443, maybe this actually fix / improves them and maybe there is another issue with my codebase. |
@soulomoon Thank you for this code. I've tested it with the replication depicted in #4443 (comment) (after rebasing the replication code on the commit just before this MR). What I can observe: With commit before this MR:
With this commit from this MR:
This is an awesome success! I unfortunately do not understand the implementation so I cannot comment more than that, but this is awesome and should be merged ASAP ;) @fendor maybe you can have a look. EDIT: I've cleaned my |
Thank you so much for your detailed feedback. I am so happy that the fix worked ! For this PR, all the compilation rules that use
Interesting, it seems to fix some thing more than I expected. I just discovered that I forget to update the rule
|
@soulomoon regarding your concern about memory usage, I've discussed that a bit in #4598 and I'm sure we can shrink the memory usage of the dependency graph by a factor 10 at a minimum. I'll try to work on that asap.
It does make sense, I suppose (and hope) that modules with template haskell do have a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These changes look very promising, thank you!
getModuleGraphSingleFileRule recorder = | ||
defineEarlyCutoff (cmapWithPrio LogShake recorder) $ Rule $ \GetFileModuleGraph file -> do | ||
di <- useNoFile_ GetModuleGraph | ||
return (fingerprintToBS <$> lookupFingerprint file di, ([], Just di)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think for correctness reasons we might need to restrict di
to only include keys in the downward dependency closure. To avoid blowing up memory usage by destroying sharing, perhaps the valid keys (downward dependency closure) should be stored in a seperate field that can be updated independent of the full Module Graph structure, and lookup operations should consult this field to check if the key to lookup is valid.
Thank you for the review @wz1000. To avoid destroying sharing, following your idea, we can do the following. useWithSeparateFingerprintRule
:: (IdeRule k v, IdeRule k1 Fingerprint)
=> k1 -> k -> NormalizedFilePath -> Action (Maybe v)
useWithSeparateFingerprintRule fingerKey key file = do
_ <- use_ fingerKey file
useWithoutDependency key emptyFilePath |
GetModuleGraphTransDepsFingerprints,GetModuleGraphTransReverseDepsFingerprints,GetModuleGraphImmediateReverseDepsFingerprints.
Since we are not restrict it before, it should fine if we are not doing it right away. But indeed it might be a good idea to implement the restriction to ensure the correctness. Also I am a bit worried about the performance impact doing the restriction. Givem the above, I'll open another PR to do it. |
defineEarlyCutoff (cmapWithPrio LogShake recorder) $ Rule $ \GetModuleGraphTransDepsFingerprints file -> do | ||
di <- useNoFile_ GetModuleGraph | ||
let finger = lookupFingerprint file di (depTransDepsFingerprints di) | ||
return (fingerprintToBS <$> finger, ([], finger)) | ||
defineEarlyCutoff (cmapWithPrio LogShake recorder) $ Rule $ \GetModuleGraphTransReverseDepsFingerprints file -> do | ||
di <- useNoFile_ GetModuleGraph | ||
let finger = lookupFingerprint file di (depTransReverseDepsFingerprints di) | ||
return (fingerprintToBS <$> finger, ([], finger)) | ||
defineEarlyCutoff (cmapWithPrio LogShake recorder) $ Rule $ \GetModuleGraphImmediateReverseDepsFingerprints file -> do | ||
di <- useNoFile_ GetModuleGraph | ||
let finger = lookupFingerprint file di (depImmediateReverseDepsFingerprints di) | ||
return (fingerprintToBS <$> finger, ([], finger)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the future, I think this should be a function moduleGraphRules
Just follow implementation from #4443 (comment) @guibou very good bisect and findings