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を選びました.
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);  
    }