FindBugs warning: Inefficient use of keySet iterator instead of entrySet iterator

前端 未结 5 1556
别跟我提以往
别跟我提以往 2021-02-06 23:20

Please refer to the following method :

public Set getCellsInColumn(String columnIndex){
    Map cellsMap = getCell         


        
5条回答
  •  离开以前
    2021-02-06 23:30

    If somebody is still interested in a detailed and number-backed answer: yes, you should use entrySet() vs. keySet() in case you are iterating over the whole Map. See this Gist for detailed numbers. I run a benchmark with JMH for the default implementations of Map with Oracle JDK8.

    The main finding is: it is always a bit slower to iterate over the keySet and re-query for every key. As soon as you have bigger maps, the multiplier can become quite big (e.g., for a ConcurrentSkipListMap it is always 5-10x; while for HashMaps it is not bigger than 2x for up to a million entries).

    However, these are still very small numbers. The slowest way to iterate over 1 million entries is with a ConcurrentSkipListMap.keySet(), which is around 500-700 milliseconds; while iterating over over IdentityHashMap.entrySet() is just 25-30 milliseconds with LinkedHashMap.entrySet() just behind with 40-50 milliseconds (not surprising, as it has a LinkedList inside it, which helps with iteration). As an overview from the above linked Gist:

    Map type              | Access Type | Δ for 1M entries
    ----------------------+-------------+-----------------
    HashMap               | .entrySet() |     69-72  ms
    HashMap               |   .keySet() |     86-94  ms
    ConcurrentHashMap     | .entrySet() |     72-76  ms
    ConcurrentHashMap     |   .keySet() |     87-95  ms
    TreeMap               | .entrySet() |    101-105 ms
    TreeMap               |   .keySet() |    257-279 ms
    LinkedHashMap         | .entrySet() |     37-49  ms
    LinkedHashMap         |   .keySet() |     89-120 ms
    ConcurrentSkipListMap | .entrySet() |     94-108 ms
    ConcurrentSkipListMap |   .keySet() |    494-696 ms
    IdentityHashMap       | .entrySet() |     26-29  ms
    IdentityHashMap       |   .keySet() |     69-77  ms
    

    So the bottom line is: it depends on your use-case. While it is definitely faster to iterate over the entrySet() the numbers are not huge, especially for reasonably small Maps. However, if you are iterating over a Map with 1 million entries quite regularly, better use the faster way ;)

    The numbers of course are just to compare with each other, not absolutes.

提交回复
热议问题