I dislike the map implementation in Java because it instantiates a new Iterator & Entry all the time. Here's an implementation of my own Map, it also has way more functionality. For example, you can multiple entries with the same key, and there are various methods to manipulate those entries.

Here's the output comparing HashMap and my implementation:

Quote

HashMap.put: 0 us 115.082 ns per entryCyclicMap.put: 0 us 088.690 ns per entryHashMap.get: 0 us 065.522 ns per entryCyclicMap.get: 0 us 043.357 ns per entryHashMap.entrySet: 0 us 003.988 ns per entryCyclicMap.entries: 0 us 003.549 ns per entryHashMap.keySet: 0 us 003.832 ns per entryCyclicMap.keys: 0 us 003.499 ns per entryHashMap.values: 0 us 003.869 ns per entryCyclicMap.values: 0 us 003.505 ns per entry

Mine obviously is only slightly better, but given all the functionality I added I'm kinda suprised I can easily match HashMap in speed.

Here's the description of the class:

Quote

A map with circular references so that all entries have a next entry and the table is pre-populated with null-key and null-value entries to hold the initial chain of entries. Having circular references enables quick iteration of entries. This map implementation also supports multiple entries with the same key value via the add(Object, Object) method.

There are also supporting methods to handle multiple values like entriesWithValue(Object), removeAllValue(Iterable), removeAllValue(Object), getAllKeys(Object, Collection), and countOfValue(Object).

This map implementation caches iterators for it's entries, values, keys, entries with a specific key, and entries with a specific value. This is to avoid needless allocation of iterators. The one drawback with this design however is that you must avoid nested iterations over the same iterator - this will not work.

This map implementation can also cache entries and reuse them between all instances via the initPool(int) method.

This map was built with speed and minimizing garbage in mind.

The fields of the Entry class are all public, do not modify these values.

Java 7 server VMHashMap.put: 0 us 031.052 ns per entryCyclicMap.put: 0 us 027.538 ns per entryHashMap.get: 0 us 008.564 ns per entryCyclicMap.get: 0 us 008.765 ns per entryHashMap.keySet: 0 us 000.116 ns per entryCyclicMap.keys: 0 us 002.420 ns per entryHashMap.entrySet: 0 us 000.109 ns per entryCyclicMap.entries: 0 us 002.361 ns per entryHashMap.values: 0 us 000.108 ns per entryCyclicMap.values: 0 us 002.380 ns per entry

Java 7 client VMHashMap.put: 0 us 048.839 ns per entryCyclicMap.put: 0 us 054.689 ns per entryHashMap.get: 0 us 025.714 ns per entryCyclicMap.get: 0 us 021.434 ns per entryHashMap.keySet: 0 us 000.157 ns per entryCyclicMap.keys: 0 us 002.393 ns per entryHashMap.entrySet: 0 us 000.178 ns per entryCyclicMap.entries: 0 us 002.409 ns per entryHashMap.values: 0 us 000.157 ns per entryCyclicMap.values: 0 us 002.417 ns per entry

Be careful with microbenchmarks.You need to let the VM warm up, especially if the slow implementation comes first each time.I ran the test with 204800 iterations each.There are empty loops which might got optimized.

Java 7 server VMHashMap.put: 0 us 031.052 ns per entryCyclicMap.put: 0 us 027.538 ns per entryHashMap.get: 0 us 008.564 ns per entryCyclicMap.get: 0 us 008.765 ns per entryHashMap.keySet: 0 us 000.116 ns per entryCyclicMap.keys: 0 us 002.420 ns per entryHashMap.entrySet: 0 us 000.109 ns per entryCyclicMap.entries: 0 us 002.361 ns per entryHashMap.values: 0 us 000.108 ns per entryCyclicMap.values: 0 us 002.380 ns per entry

Java 7 client VMHashMap.put: 0 us 048.839 ns per entryCyclicMap.put: 0 us 054.689 ns per entryHashMap.get: 0 us 025.714 ns per entryCyclicMap.get: 0 us 021.434 ns per entryHashMap.keySet: 0 us 000.157 ns per entryCyclicMap.keys: 0 us 002.393 ns per entryHashMap.entrySet: 0 us 000.178 ns per entryCyclicMap.entries: 0 us 002.409 ns per entryHashMap.values: 0 us 000.157 ns per entryCyclicMap.values: 0 us 002.417 ns per entry

Be careful with microbenchmarks.You need to let the VM warm up, especially if the slow implementation comes first each time.I ran the test with 204800 iterations each.There are empty loops which might got optimized.

Any who, I wonder how HashMap's values(), entrySet(), and keySet() are so low for you? Something must be going on with my code that it's getting treated differently by the VM.

Because you clear the map while measuring.Also, the warm up period should be separated from the measuring part but running the exact same code.Then I would rather measure the time for one complete iteration set to prevent timer inaccuracies and for benchmarking hash maps I would create a more random set of key values.

Also, the warm up period should be separated from the measuring part but running the exact same code.

Whys that?

Just because compiling hot spots takes time and could distort the measurements.On slower machines it is clearly noticable that the server vm does a quiet aggressive compilation and optimization job.According to the "Java Performance" book, the server VM needs 10000 iterations before it compiles to native code and the client VM 1500 iterations.

His micro benchmark is poor. JAVA_HASH, etc aren't final, currentTimeMillis, no warmup, etc. Plus I doubt Java's HashMap double hashing is what makes it slow. It degrades to a linked list when hashing is poor (lots of .equals()!) and it allocates on put().

The usefulness of a micro benchmark is questionable, but the uselessness of a flawed micro benchmark isn't. So, his benchmark doesn't say anything about how much faster it is. My main point though is that even if you made the second hashing instantaneous, I doubt you would have sped up HashMap. In other words, the hashing isn't what is slow.

java-gaming.org is not responsible for the content posted by its members, including references to external websites,
and other references that may or may not have a relation with our primarily
gaming and game production oriented community.
inquiries and complaints can be sent via email to the info‑account of the
company managing the website of java‑gaming.org