Repository navigation
Speed up find_matching_direct_imports - #334
Conversation
An expression with no wildcards can only match the module with that name. Look that module up directly, instead of checking the expression against the name of every module in the graph. Assistant-model: Claude Code
Previously this checked every import in the graph against both expressions, which made each call proportional to the size of the graph. This is slow when it is called many times, as Import Linter does for each of the expressions in a contract's ignore_imports. Instead, find the modules that match each expression, then only look at the imports of the modules that match the importer expression. Assistant-model: Claude Code
Merging this PR will improve performance by 57.75%
Performance Changes
Tip Curious why performance improved? Comment Comparing Footnotes
|
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues remain for the module and direct-import matching optimizations.
No open issues 🎉
What changed in this PR
Speeds up module and direct-import matching in Grimp, reducing the work needed for Import Linter’s ignore expressions while preserving the public API and matching results.
Changes:
- Uses direct module lookup for expressions without wildcards.
- Restricts direct-import searches to matching importer modules and filters their imports against matching targets.
- Adds Python and Rust regression cases and documents the optimizations.
| File | Description |
|---|---|
| tests/unit/application/graph/test_direct_imports.py | Adds coverage for exact names, wildcards, missing modules, and empty results. |
| rust/src/graph/hierarchy_queries.rs | Adds direct lookup for wildcard-free expressions and associated tests. |
| rust/src/graph/direct_import_queries.rs | Limits import traversal to matching importers and adds regression tests. |
| CHANGELOG.rst | Records both performance improvements under latest. |
Review effort: Balanced
Motivation
Import Linter's
ignore_importscallsfind_matching_direct_importsonce for each expression in a contract's ignore list. Each call checked every import in the graph against both expressions, so the cost of each call grew with the size of the graph, even though most expressions only match a handful of modules.On a large code base (about 150k modules and 1M imports), resolving 1,262 expressions took about 19s. That is a large share of the time Import Linter spends on some contracts.
Changes
Two commits:
find_matching_modules: an expression with no wildcards can only match the module with that name, so look it up directly instead of checking every module.find_matching_direct_imports: find the modules that match each expression, then only look at the imports of the modules that match the importer expression.There are no API changes, and the results are the same.
Results
On the same graph:
The results were identical for every expression.