ac7e950d38
Our calculation of initOrder builds the dependency graph and then removes function nodes approximately at random. While profiling, I noticed that this latter step introduces a superlinear algorithm into our type checking pass, which can dominate type checking for large packages such as runtime. It is hard to analyze this rigorously, but to give an idea of how such a non-linearity could arise, suppose the following assumptions hold: - Every function makes D calls at random to other functions in the package, for some fixed constant D. - The number of functions is proportional to N, the size of the package. Under these simplified assumptions, the cost of removing an arbitrary function F is P*D, where P is the expected number of functions calling F. P has a Poisson distribution with mean D. Now consider the fact that when removing a function F in position i, we recursively pay the cost of copying F's predecessors and successors for each node in the remaining unremoved subgraph of functions containing F. With our assumptions, the size of this subgraph is proportional to (N-i), the number of remaining functions to remove. Therefore, the total cost of removing functions is proportional to P*D*Σᴺ(N-i) which is proportional to N². However, if we remove functions in ascending order of cost, we can partition by the number of predecessors, and the total cost of removing functions is proportional to N*D*Σ(PMF(X)) where PMF is the probability mass function of P. In other words cost is proportional to N. Assuming the above analysis is correct, it is still the case that the initial assumptions are naive. Many large packages are more accurately characterized as combinations of many smaller packages. Nevertheless, it is intuitively clear that removing expensive nodes last should be cheaper. Therefore, we sort by cost first before removing nodes in dependencyGraph. We also move deletes to the outer loop, to avoid redundant deletes. By inspection, this avoids a bug where n may not have been removed from its successors if n had no predecessors. name old time/op new time/op delta Check/runtime/funcbodies/noinfo-8 568ms ±25% 82ms ± 1% -85.53% (p=0.000 n=8+10) name old lines/s new lines/s delta Check/runtime/funcbodies/noinfo-8 93.1k ±56% 705.1k ± 1% +657.63% (p=0.000 n=10+10) Updates #49856 Change-Id: Id2e70d67401af19205e1e0b9947baa16dd6506f0 Reviewed-on: https://go-review.googlesource.com/c/go/+/369434 Trust: Robert Findley <rfindley@google.com> Run-TryBot: Robert Findley <rfindley@google.com> Reviewed-by: Robert Griesemer <gri@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> |
||
---|---|---|
.github | ||
api | ||
doc | ||
lib/time | ||
misc | ||
src | ||
test | ||
.gitattributes | ||
.gitignore | ||
AUTHORS | ||
codereview.cfg | ||
CONTRIBUTING.md | ||
CONTRIBUTORS | ||
LICENSE | ||
PATENTS | ||
README.md | ||
SECURITY.md |
The Go Programming Language
Go is an open source programming language that makes it easy to build simple, reliable, and efficient software.
Gopher image by Renee French, licensed under Creative Commons 3.0 Attributions license.
Our canonical Git repository is located at https://go.googlesource.com/go. There is a mirror of the repository at https://github.com/golang/go.
Unless otherwise noted, the Go source files are distributed under the BSD-style license found in the LICENSE file.
Download and Install
Binary Distributions
Official binary distributions are available at https://golang.org/dl/.
After downloading a binary release, visit https://golang.org/doc/install for installation instructions.
Install From Source
If a binary distribution is not available for your combination of operating system and architecture, visit https://golang.org/doc/install/source for source installation instructions.
Contributing
Go is the work of thousands of contributors. We appreciate your help!
To contribute, please read the contribution guidelines at https://golang.org/doc/contribute.
Note that the Go project uses the issue tracker for bug reports and proposals only. See https://golang.org/wiki/Questions for a list of places to ask questions about the Go language.