-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Cache all packages.Load calls in a central object #988
Conversation
I'm seeing pretty different results from you: package-cache master (ae79e75) v0.10.2 v0.10.1 (without skip_validation and without disabling model generation) no-double-load (rebased on master) |
The app I'm testing against has:
I cant see any reason this should be any slower than no-double-load, it should be loading the same packages but fewer times. Could you try running this branch with this patch applied to log each call to packages.Load?
to see whats actually getting loaded when? compare with something similar on no-double-load? |
Here's a redacted version of what I'm seeing with your print statements. I added "MISSING" on line 47 to differentiate the two places where loads happen.
I think the big difference between multiple load calls and one big load call is that shared dependencies of the various packages. Our codebase is more tightly coupled than I would like and there's a lot of overlap between dependencies from each call. I did an experiment: multiLoadTest: package main
import "golang.org/x/tools/go/packages"
var mode = packages.NeedName |
packages.NeedFiles |
packages.NeedImports |
packages.NeedTypes |
packages.NeedSyntax |
packages.NeedTypesInfo
func main() {
packages.Load(&packages.Config{Mode: mode}, "redacted")
...
packages.Load(&packages.Config{Mode: packages.NeedName}, "github.com/vektah/gqlparser")
packages.Load(&packages.Config{Mode: mode}, "redacted")
} singleLoadTest: package main
import "golang.org/x/tools/go/packages"
var mode = packages.NeedName |
packages.NeedFiles |
packages.NeedImports |
packages.NeedTypes |
packages.NeedSyntax |
packages.NeedTypesInfo |
packages.NeedName
func main() {
_, err := packages.Load(&packages.Config{Mode: mode}, redacted)
if err != nil {
panic(err)
}
} multiLoadTest:
singleLoadTest:
The conclusion is that this PR actually makes the situation worse, not better. Could you share the results of adding the print statements for your repo? Can you try running my experiment with your set of loads? |
btw, we have autobind on, validation off and model generation off |
Interesting. This PR should be doing a single load. Why aren't redacted being covered by ReferencedPackages in this branch but they are in package-cache? |
I'm going to roll forward with this - This gives us speed gains for the apps we can test with and centralizes a bunch of loading logic. Would love to get to the bottom of why ReferencedPackages isnt covering your deps but that can happen on master. |
Cache all packages.Load calls in a central object
The idea here is to have a central proxy to packages.Load that can be invalidated as files are written out, reducing the number of package.Load calls way down.
Would love to get your thoughts @vikstrous.
Alternative to #945 and #943 that includes some fairly heavy refactor.
Updated timing for one of our apps:
v0.10
real 0m7.437s
user 0m17.978s
sys 0m1.751s
master
real 0m5.677s
user 0m10.742s
sys 0m1.205s
package-cache
real 0m2.987s
user 0m5.286s
sys 0m0.608s