Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
AST: More efficient way to collect referenced source units
Previous implementation of the method SourceUnit::referencedSourceUnits contained a subtle performance bug. Because the skip list was passed by value into the recursive call, the dependency graph of the imports were effectively traversed as if expanded into a full tree, instead of as a DAG (directed acyclic graph). An example to illustrate that previously the same source was visited more than once: Suppose `A.sol` imports `B.sol` and `C.sol` and both of these import `D.sol`. Previosuly, the method would process `A` by first recursing into `B` and then `C`. When processing `B`, the source `D` is processed and then added to the skip list. When the recursion returns from processing `B`, any changes made to the skip list there were discarded, so that during processing `C`, the source `D` is not find in the skip list and processed again. Now, in most cases the import/dependency graph is probably shallow or does not contain such diamond-like subgraphs, and the performance is not affected. However, for a deeper dependency graph with multiple layers of diamond-like subgraphs this quickly leads to very bad performance, because every source unit is visited a number of times equal to the number of paths by which the source unit is reachable from the root source unit. This change seems to shave off *tens* of seconds on **both** legacy and ir pipeline for `sablier-v2-1.2.0` project.
- Loading branch information