Friday 3 December 2010

Performance: use Map.Entry instead of itrating the KeySet

using Map.Entry shows more performace than KeySet, The reason is that, once you need to access every key (and its value), you don't need to call the get() function on each of them. Because keys and values in a Map are already stored internally as a Map.Entry instance in next pointer to each other. so that when you iterate an EntrySet, you're just accessing these elements directly.
If you call get() function instead, you invoke the hashCode() function internally and causing the HashMap to do a lookup in its internal array.

to prove this, I wrote this sample test, the first test uses KeySet and the seconds one, the Map.Entry method.
As you see, using KeySet takes 110 miliseconds against 78 miliseconds that Map.Entry takes.



public class IterateMapTest {
    private final static Map<Integer, Float> testMap = new HashMap<Integer, Float>();
    
    @BeforeClass
    public static void initMap() {
        final Random random = new Random(100000);
        for (int i = 0; i < 1000000; i ++) {
            testMap.put(random.nextInt(), random.nextFloat());
        }
    }
    
    @Test
    public void testIterateMapKeySet() {
        final long startTime = System.currentTimeMillis();
        
        for (Integer entry : testMap.keySet())
            

        System.out.println("testIterateMapKeySet -> Time elapsed: " (System.currentTimeMillis() - startTime));
    }

    @Test
    public void testIterateMapEntry() {
        final long startTime = System.currentTimeMillis();
        
        for (Map.Entry<Integer, Float> entry : testMap.entrySet())
            ;

        System.out.println("testIterateMapEntry -> Time elapsed: " (System.currentTimeMillis() - startTime));
    }
}



Output:
testIterateMapKeySet -> Time elapsed: 110
testIterateMapEntry -> Time elapsed: 78


 

No comments:

Post a Comment