On large codebases, the high number of calls to Find.find (which builds a recursive list of all files in directory and subdirectories) for every single file to lint (Find.find called on each iteration of the reject {…} and select {…} loops) ends up iterating on the whole file hierarchy multiple times, and affects performance.
How?
Just stored the result of Find.find(*excluded_path) and Find.find(*included_path) in a local array so that it iterates only once, then used that pre-computed local array inside each iteration of reject/select
Result
We just had a CircleCI timeout because of that performance issue, which made swiftlint.lint_files exceed the 10 minutes job timeout. On contrast, once pointing to this patch, the lint only took a few seconds.
Why?
On large codebases, the high number of calls to
Find.find
(which builds a recursive list of all files in directory and subdirectories) for every single file to lint (Find.find
called on each iteration of thereject {…}
andselect {…}
loops) ends up iterating on the whole file hierarchy multiple times, and affects performance.How?
Just stored the result of
Find.find(*excluded_path)
andFind.find(*included_path)
in a local array so that it iterates only once, then used that pre-computed local array inside each iteration ofreject
/select
Result
We just had a CircleCI timeout because of that performance issue, which made
swiftlint.lint_files
exceed the 10 minutes job timeout. On contrast, once pointing to this patch, the lint only took a few seconds.