Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HashMap vs Switch statement performance

A HashMap essentially has O(1) performance while a switch state can have either O(1) or O(log(n)) depending on if the compiler uses a tableswitch or lookup switch.

Understandably, if a switch statement is written as such,

switch (int) {     case 1:     case 2:     case 3:     case 4:     default: } 

then it would use a tableswitch and clearly have a performance advantage over a standard HashMap. But what if the switch statement is sparse? These would be two examples that I would be comparing:

HashMap<Integer, String> example = new HashMap<Integer, String>() {{         put(1, "a");         put(10, "b");         put(100, "c");         put(1000, "d"); }}; 

.

switch (int) {     case 1:         return "a";     case 10:         return "b";     case 100:         return "c";     case 1000:         return "d";     default:         return null; } 

What would provide more throughput, a lookupswitch or HashMap? Does the overhead of the HashMap give the lookupswitch an advantage early but eventually tapers off as the number of cases/entries increase?

Edit: I tried some benchmarks using JMH, here are my results and code used. https://gist.github.com/mooman219/bebbdc047889c7cfe612 As you guys mentioned, the lookupswitch statement outperformed the HashTable. I'm still wondering why though.

like image 739
Joe C Avatar asked Jan 16 '15 22:01

Joe C


People also ask

Is HashMap faster than if-else?

The if-else will be faster. The hashmap has to do more commands to get you there. Fetch hashcode, calculate distance/position, fetch the array entry, and run an equals operation.

Which is faster HashMap or array?

According to a stackoverflow post, "HashMap uses an array underneath so it can never be faster than using an array correctly".

Is switch faster than if-else Java?

Speed: A switch statement might prove to be faster than ifs provided number of cases are good. If there are only few cases, it might not effect the speed in any case. Prefer switch if the number of cases are more than 5 otherwise, you may use if-else too.

Why is HashMap faster?

The reason that HashMap is faster than HashSet is that the HashMap uses the unique keys to access the values. It stores each value with a corresponding key and we can retrieve these values faster using keys during iteration. While HashSet is completely based on objects and therefore retrieval of values is slower.


1 Answers

The accepted answer is wrong here.

http://java-performance.info/string-switch-implementation/

Switches will always be as fast as if not faster than hash maps. Switch statements are transformed into direct lookup tables. In the case of Integer values (ints, enums, shorts, longs) it is a direct lookup/jmp to the statement. There is no additional hashing that needs to happen. In the case of a String, it precomputes the string hash for the case statements and uses the input String's hashcode to determine where to jump. In the case of collision, it does an if/else chain. Now you might think "This is the same as HashMap, right?" But that isn't true. The hash code for the lookup is computed at compile time and it isn't reduced based on the number of elements (lower chance of collision).

Switches have O(1) lookup, not O(n). (Ok, in truth for a small number of items, switches are turned into if/else statements. This provides better code locality and avoids additional memory lookups. However, for many items, switches are changed into the lookup table I mentioned above).

You can read more about it here How does Java's switch work under the hood?

like image 171
Cogman Avatar answered Sep 20 '22 08:09

Cogman