JAva HashMap統計数を用いた性能比較
以前、javaカウントを記述する投稿を偶然見たが、Integerの分析を見たが、カスタムのMutableIntegerをカウントし、性能が向上した.
以前はMapカウントの場合も使われていましたが、1.8に導入されたFIに興味があり、会社も1.8に更新したので、1.8の新しい特性を利用してこのカウントをしました.
これは何度くらいで比較平均的な数値(万悪のGC...)
Naive Approach : 156887211Better Approach: 90908291Efficient Approach: 91313854{one=1000000, two=2000000, three=3000000}Fi 1.8 MutableInteger: 70158595{one=1000000, three=3000000, two=2000000}Fi 1.8 配列: 106869821{one=[I@15db9742, three=[I@6d06d69c, two=[I@7852e922}Fi 1.8 Integer : 82991748{one=1000000, three=3000000, two=2000000} 配列: 55290882{one=[I@4e25154f, two=[I@70dea4e, three=[I@5c647e05}Fi 1.8 Atomic: 80224945{one=1000000, three=3000000, two=2000000}
最後にfi AtomicIntegerを選びました.
以前はMapカウントの場合も使われていましたが、1.8に導入されたFIに興味があり、会社も1.8に更新したので、1.8の新しい特性を利用してこのカウントをしました.
これは何度くらいで比較平均的な数値(万悪のGC...)
Naive Approach : 156887211Better Approach: 90908291Efficient Approach: 91313854{one=1000000, two=2000000, three=3000000}Fi 1.8 MutableInteger: 70158595{one=1000000, three=3000000, two=2000000}Fi 1.8 配列: 106869821{one=[I@15db9742, three=[I@6d06d69c, two=[I@7852e922}Fi 1.8 Integer : 82991748{one=1000000, three=3000000, two=2000000} 配列: 55290882{one=[I@4e25154f, two=[I@70dea4e, three=[I@5c647e05}Fi 1.8 Atomic: 80224945{one=1000000, three=3000000, two=2000000}
最後にfi AtomicIntegerを選びました.
public static void main(String[] args) {
String s = "one two three two three three";
String[] sArr = s.split(" ");
long startTime = 0;
long endTime = 0;
long duration = 0;
// naive approach
startTime = System.nanoTime();
HashMap counter = new HashMap();
for (int i = 0; i < 1000000; i++)
for (String a : sArr) {
if (counter.containsKey(a)) {
int oldValue = counter.get(a);
counter.put(a, oldValue + 1);
} else {
counter.put(a, 1);
}
}
endTime = System.nanoTime();
duration = endTime - startTime;
System.out.println("Naive Approach : " + duration);
// better approach
startTime = System.nanoTime();
HashMap newCounter = new HashMap();
for (int i = 0; i < 1000000; i++)
for (String a : sArr) {
if (newCounter.containsKey(a)) {
MutableInteger oldValue = newCounter.get(a);
oldValue.set(oldValue.get() + 1);
} else {
newCounter.put(a, new MutableInteger(1));
}
}
endTime = System.nanoTime();
duration = endTime - startTime;
System.out.println("Better Approach: " + duration);
// efficient approach
startTime = System.nanoTime();
HashMap efficientCounter = new HashMap();
for (int i = 0; i < 1000000; i++)
for (String a : sArr) {
MutableInteger initValue = new MutableInteger(1);
MutableInteger oldValue = efficientCounter.put(a, initValue);
if (oldValue != null) {
initValue.set(oldValue.get() + 1);
}
}
endTime = System.nanoTime();
duration = endTime - startTime;
System.out.println("Efficient Approach: " + duration+efficientCounter);
// Fi 1.8 MutableInteger
startTime = System.nanoTime();
HashMap functionInterfaceCounter = new HashMap();
for (int i = 0; i < 1000000; i++)
for (String a : sArr) {
functionInterfaceCounter.compute(a, new BiFunction() {
@Override
public MutableInteger apply(String k, MutableInteger v) {
if (v == null)
v=new MutableInteger(0);
v.set(v.get()+1);;
return v;
}
});
}
endTime = System.nanoTime();
duration = endTime - startTime;
System.out.println("Fi 1.8 MutableInteger: " + duration+functionInterfaceCounter);
// Fi 1.8
startTime = System.nanoTime();
HashMap ficounter2 = new HashMap();
for (int i = 0; i < 1000000; i++)
for (String a : sArr) {
ficounter2.compute(a, new BiFunction() {
@Override
public int[] apply(String k, int[] v) {
if (v == null)
v=new int[]{0};
v[0]++;
return v;
}
});
}
endTime = System.nanoTime();
duration = endTime - startTime;
System.out.println("Fi 1.8 : " + duration+ficounter2);
// Fi 1.8
startTime = System.nanoTime();
HashMap integercounter2 = new HashMap();
for (int i = 0; i < 1000000; i++)
for (String a : sArr) {
integercounter2.compute(a, new BiFunction() {
@Override
public Integer apply(String k, Integer v) {
if (v == null)
v=0;
v++;
return v;
}
});
}
endTime = System.nanoTime();
duration = endTime - startTime;
System.out.println("Fi 1.8 Interger : " + duration+integercounter2);
//
startTime = System.nanoTime();
HashMap intCounter = new HashMap();
for (int i = 0; i < 1000000; i++)
for (String a : sArr) {
int[] valueWrapper = intCounter.get(a);
if (valueWrapper == null) {
intCounter.put(a, new int[] { 0 });
} else {
valueWrapper[0]++;
}
}
endTime = System.nanoTime();
duration = endTime - startTime;
System.out.println(" : " + duration+intCounter);
// Fi 1.8 Autonomicinteger
startTime = System.nanoTime();
HashMap autonomicCounter = new HashMap();
for (int i = 0; i < 1000000; i++)
for (String a : sArr) {
autonomicCounter.compute(a, new BiFunction() {
@Override
public AtomicInteger apply(String k, AtomicInteger v) {
if (v == null)
v=new AtomicInteger(0);
v.getAndIncrement();
return v;
}
});
}
endTime = System.nanoTime();
duration = endTime - startTime;
System.out.println("Fi 1.8 Atomic: " + duration+autonomicCounter);
}
}
class MutableInteger {
private int val;
public MutableInteger(int val) {
this.val = val;
}
public int get() {
return val;
}
public void set(int val) {
this.val = val;
}
//used to print value convinently
public String toString() {
return Integer.toString(val);
}