Optimize resource lookup in DevTools restart #46289
Open
+38
−33
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.
Optimize resource lookup in DevTools restart
This pull request significantly improves the performance of resource lookups within the DevTools restart mechanism, particularly benefiting projects with a large number of files and source directories.
Motivation and Problem
The existing
ClassLoaderFilesResourcePatternResolver
and its underlyingClassLoaderFiles
implementation suffer from performance degradation in large-scale projects. Key methods such asgetFile()
,size()
,isDeleted()
, andgetAdditionalResources()
rely on nested loops that iterate through all source directories and their respective files. This results in a time complexity of O(n*m) for many critical operations, where 'n' is the number of source directories and 'm' is the number of files. As a project grows, these repeated iterations can introduce noticeable delays during application restarts.Solution
This PR addresses the performance bottleneck by refactoring
ClassLoaderFiles
to use a pre-computed, flattened map for direct lookups, and updatingClassLoaderFilesResourcePatternResolver
to leverage this new, efficient structure.1.
ClassLoaderFiles
Refactoring:A new
Map<String, ClassLoaderFile> filesByName
field has been added. This map is populated once at construction time and serves as a unified, central cache for all files across all source directories.getFile(name)
now performs a directget()
on thefilesByName
map, reducing its complexity from O(n) to O(1).size()
now directly returnsfilesByName.size()
, reducing its complexity from O(n) to O(1).The
addFile()
andremoveAll()
methods have been updated to ensure that both the originalsourceDirectories
map and the newfilesByName
map are kept in sync, guaranteeing data integrity.A new
getFileEntries()
method provides a way to iterate over all files in a single loop, which is used by the resolver.2.
ClassLoaderFilesResourcePatternResolver
Optimization:isDeleted()
:This method has been refactored to eliminate the nested loop structure (from O(n*m) to O(m)). It now iterates over the single, unified collection provided by
classLoaderFiles.getFileEntries()
, significantly reducing the complexity of the operation while preserving the original exception handling behavior.getAdditionalResources()
:Similarly, this method now iterates over the single, unified collection provided by
classLoaderFiles.getFileEntries()
, eliminating the outer loop and improving readability and performance.Benefits
Significant Performance Improvement:
Reduces the time complexity of critical file lookup operations. Direct lookups like
getFile
are improved from O(n) to O(1), while iterative searches likeisDeleted
are improved from O(n*m) to O(m), leading to faster application restarts in DevTools.Enhanced Code Quality:
Eliminates nested loops, which simplifies the code, improves readability, and makes the logic easier to maintain.
Minimal Memory Overhead:
The optimization introduces a map of references, not data duplicates. The trade-off of a negligible increase in memory usage for a substantial performance gain is highly favorable.
This change maintains full backward compatibility with the existing API while providing a much-needed performance boost for developers working on large applications.