AjaxRequestHandler: Keep listeners in a LinkedHashSet instead of LinkedList for performance reason #438
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.
While migrating my project (see PR there) from the mocking library mockito to mock, I ran into weird performance issues. The build time jumped from roughly 20 minutes to eventually more than 4 hours. I took some effort improving various things in my own code (less mocking, more memory etc.) but did not bring it down considerably until I addressed a bottleneck I found in wicket.
AjaxRequestHandler
maintains a collection of listeners in aLinkedList
. When client code adds a new listener calling methodaddListener
, it uses the collection's methodcontains
to assert we don't add a listener to the collection twice. This doesn't scale well. For some reason, my setup with mockk seems to add many more listeners than what my code did with mockito, so I ran into this issue with continuously slower test executions.I managed to temporarily resolve the problem in my project by plugging in my own copy of AjaxRequestHandler where I swapped the collection type from LinkedList to LinkedHashSet (calling
setAjaxRequestTargetProvider
in my TestApplication). With this approach the total build time went down again to 20-30 minutes.This PR serves the purpose of starting a discussion about whether this change would be feasible to implement in wicket directly. To me, it is not apparent why a LinkedList had been chosen initially. The LinkedHashSet performs much better with contains and still preserves insertion order. If that latter should turn out to be not relevant, we could even consider using a HashSet instead of a linked HashSet, but I presume insertion order is important.
A separate topic on my side will be to figure out why my setup with mockito seemed to work well while migrating to mockk surfaced this issue.