Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Hey @weavejester,
I've noticed that
lein-ring
starts really slow for larger projects (for example it usually takes 15-20 minutes to launch Metabase vialein ring server
, compared to ~1 withlein run
).I did some profiling and determined 98% of the launch time was spent in
ns-tracker.dependency/transitive
, mainly because it recursively callstransitive
on everything before finally removing duplicates inseq-union
. I changed this to an implementation that avoids recursive calls for dependencies that have already been dealt with, which has pretty dramatic performance improvements.To test this I captured a real-world graph of ~200 namespaces from Metabase during launch and compared the old and new implementations. The namespaces graph and code I used to compare implementations is here if you'd like to see for yourself. When testing locally, the new implementation is around 1000x faster:
I can also confirm that it has fixed the slow launch time issue I was running into.
The order of results in the new implementation are consistently breadth-first whereas results in the old implementation are mostly breadth-first but, not consistently so. I put an example comparison between the orders returned by the implementations here. As far as I can tell the slight order differences has no effect on the reloading code that relies on it.