Hello,
I’ve just come across the package:
http://gongolo.usr.dsi.unimi.it/~vigna/fastUtil/
It provides specializations for Maps. F.E. instead of using a HashMap
with key=Integer, value=Integer you would use an Int2IntHashMap where key=int, value=int.
In a microbenchmark I have found that the Int2IntHashMap can be up
to 30 times faster than java.util.HashMap.
fwiw, 30 = 7272727/236966 where:
- 7272727 = 2nd iteration of Int2IntHashMap!
- 236966 = 15th iteration of HashMap (Hot spot had 12 more iterations to optimize)
On top of this, (and the reason for the number 30 above) is that using HashMaps can cause a lot of GC work.
The code and the results follow:
//
// $Id: TestFastUtil.java,v 1.4 2002/11/18 01:09:19 mswanson Exp $
//
package com.wss.utils.test;
import java.util.;
import it.unimi.dsi.fastUtil.;
/**
*
*/
public class TestFastUtil {
public static void main(String[] args) throws Exception {
int count = 400000;
int timerCount = 20;
long start, end;
Integer tmp;
// Normal HashMap
HashMap hashMap = new HashMap(count);
for (int timer=0; timer < timerCount; ++timer) {
start = System.currentTimeMillis();
for (int i=0; i < count; ++i) {
hashMap.put(new Integer(i), new Integer(i));
}
end = System.currentTimeMillis();
System.out.println("HashMap put(Integer, Integer) count:" + count +
", put/s:" + (count / ((float)(end-start) / (float)1000)));
start = System.currentTimeMillis();
for (int i=0; i < count; ++i) {
Integer in = new Integer(i);
tmp = (Integer)hashMap.get(in);
if (!tmp.equals(in))
throw new Exception("failed equals()");
}
end = System.currentTimeMillis();
System.out.println("HashMap get(Integer) count:" + count +
", get/s:" + (count / ((float)(end-start) / (float)1000)));
}
// FastUtil HashMap Int2Int
timerCount = 100;
Int2IntHashMap int2IntHM = new Int2IntHashMap(count);
int j;
for (int timer=0; timer < timerCount; ++timer) {
start = System.currentTimeMillis();
for (int i=0; i < count; ++i) {
int2IntHM.put(i, i);
}
end = System.currentTimeMillis();
System.out.println("Int2Int put(Integer, Integer) count:" + count +
", put/s:" + (count / ((float)(end-start) / (float)1000)));
start = System.currentTimeMillis();
for (int i=0; i < count; ++i) {
j = int2IntHM.get(i);
if (i != j)
throw new Exception("Int2Int failed equals()");
}
end = System.currentTimeMillis();
System.out.println("Int2Int get(Integer) count:" + count +
", get/s:" + (count / ((float)(end-start) / (float)1000)));
}
}
}
HashMap put(Integer, Integer) count:400000, put/s:137174.22
HashMap get(Integer) count:400000, get/s:603318.25
HashMap put(Integer, Integer) count:400000, put/s:508905.84
HashMap get(Integer) count:400000, get/s:966183.56
HashMap put(Integer, Integer) count:400000, put/s:203252.03
HashMap get(Integer) count:400000, get/s:1052631.6
HashMap put(Integer, Integer) count:400000, put/s:586510.25
HashMap get(Integer) count:400000, get/s:997506.25
HashMap put(Integer, Integer) count:400000, put/s:571428.56
HashMap get(Integer) count:400000, get/s:928074.25
HashMap put(Integer, Integer) count:400000, put/s:243013.36
HashMap get(Integer) count:400000, get/s:952381.0
HashMap put(Integer, Integer) count:400000, put/s:635930.06
HashMap get(Integer) count:400000, get/s:816326.5
HashMap put(Integer, Integer) count:400000, put/s:707964.6
HashMap get(Integer) count:400000, get/s:757575.75
HashMap put(Integer, Integer) count:400000, put/s:234879.62
HashMap get(Integer) count:400000, get/s:1111111.1
HashMap put(Integer, Integer) count:400000, put/s:492610.84
HashMap get(Integer) count:400000, get/s:975609.75
HashMap put(Integer, Integer) count:400000, put/s:583941.6
HashMap get(Integer) count:400000, get/s:915331.8
HashMap put(Integer, Integer) count:400000, put/s:626959.25
HashMap get(Integer) count:400000, get/s:275482.1
HashMap put(Integer, Integer) count:400000, put/s:686106.3
HashMap get(Integer) count:400000, get/s:781249.94
HashMap put(Integer, Integer) count:400000, put/s:571428.56
HashMap get(Integer) count:400000, get/s:1049868.8
HashMap put(Integer, Integer) count:400000, put/s:236966.83
HashMap get(Integer) count:400000, get/s:1044386.44
HashMap put(Integer, Integer) count:400000, put/s:589970.5
HashMap get(Integer) count:400000, get/s:943396.25
HashMap put(Integer, Integer) count:400000, put/s:597907.3
HashMap get(Integer) count:400000, get/s:843881.9
HashMap put(Integer, Integer) count:400000, put/s:689655.2
HashMap get(Integer) count:400000, get/s:273597.8
HashMap put(Integer, Integer) count:400000, put/s:698080.25
HashMap get(Integer) count:400000, get/s:767754.25
HashMap put(Integer, Integer) count:400000, put/s:583941.6
HashMap get(Integer) count:400000, get/s:1017811.7
Int2Int put(Integer, Integer) count:400000, put/s:3448276.0
Int2Int get(Integer) count:400000, get/s:3305785.2
Int2Int put(Integer, Integer) count:400000, put/s:7272727.5
Int2Int get(Integer) count:400000, get/s:7547170.0
Int2Int put(Integer, Integer) count:400000, put/s:7142857.0
Int2Int get(Integer) count:400000, get/s:7547170.0
Int2Int put(Integer, Integer) count:400000, put/s:7272727.5
Int2Int get(Integer) count:400000, get/s:7547170.0
Int2Int put(Integer, Integer) count:400000, put/s:7272727.5
Int2Int get(Integer) count:400000, get/s:7142857.0
Int2Int put(Integer, Integer) count:400000, put/s:7272727.5
Int2Int get(Integer) count:400000, get/s:7547170.0
Int2Int put(Integer, Integer) count:400000, put/s:7272727.5
…