From 4863f89c486effdd34a31446af87d8f06c28961b Mon Sep 17 00:00:00 2001 From: Pepijn Van Eeckhoudt Date: Thu, 19 May 2022 15:37:17 +0200 Subject: [PATCH] fix: Avoid potential slow Set#removeAll call in HierarchicalCommunicator (#13746) * fix: Avoid potential slow Set#removeAll call in HierarchicalCommunicationController#passivateInactiveKeys The performance of calling Set#removeAll(List) is dependent on the relative sizes of the Set and List parameter. Replace Set#removeAll with List#forEach(Set::remove) to avoid this. Fixes #13745 Co-authored-by: Mikhail Shabarov <61410877+mshabarov@users.noreply.github.com> Co-authored-by: Soroosh Taefi --- .../hierarchy/HierarchicalCommunicationController.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/flow-data/src/main/java/com/vaadin/flow/data/provider/hierarchy/HierarchicalCommunicationController.java b/flow-data/src/main/java/com/vaadin/flow/data/provider/hierarchy/HierarchicalCommunicationController.java index 70928dc6ef5..4b050710359 100644 --- a/flow-data/src/main/java/com/vaadin/flow/data/provider/hierarchy/HierarchicalCommunicationController.java +++ b/flow-data/src/main/java/com/vaadin/flow/data/provider/hierarchy/HierarchicalCommunicationController.java @@ -288,7 +288,14 @@ private void passivateInactiveKeys(Set oldActive, } // Finally clear any passivated items that have now been confirmed - oldActive.removeAll(newActiveKeyOrder); + /* + * Due to the implementation of AbstractSet#removeAll, if the size + * of newActiveKeyOrder is bigger than oldActive's size, then + * calling oldActive.removeAll(newActiveKeyOrder) would end up + * calling contains method for all of newActiveKeyOrder items which + * is a slow operation on lists. The following avoids that: + */ + newActiveKeyOrder.forEach(oldActive::remove); if (!oldActive.isEmpty()) { passivatedByUpdate.put(Integer.valueOf(updateId), oldActive); }