2014年8月2日土曜日

[Java] ArrayとArrayListの速度比較

小さめのサイズでArrayとArrayListの速度比較を行ってみました。

[前提]
 ・サイズは 10-100 程度
 ・リストの容量と中身の大きさはほぼ同じ
 ・用途は、更新頻度が高いイベントの配布先の管理に使う


[結果]
Arrayのforとforeachはほぼ同じ。
ArrayListでも通常のforループで回すと余り変わらない 。若干ArrayListが遅いか。
foreach、streamは遅い。foreachで2倍程度。

[Array - for]
Start : 1406987147093, End : 1406987147102, Took : 9
[Array - foreach]
Start : 1406987147122, End : 1406987147131, Took : 9
[ArrayList - for]
Start : 1406987147132, End : 1406987147142, Took : 10
[ArrayList - foreach]
Start : 1406987147142, End : 1406987147174, Took : 32
[ArrayList - stream]
Start : 1406987147174, End : 1406987147229, Took : 55


※初期容量を非常に大きくした場合
 ⇒foreachが大きく影響を受ける。
[Array - for]
Start : 1406987109799, End : 1406987109809, Took : 10
[Array - foreach]
Start : 1406987109826, End : 1406987109835, Took : 9
[ArrayList - for]
Start : 1406987109835, End : 1406987109845, Took : 10
[ArrayList - foreach]
Start : 1406987109845, End : 1406987110117, Took : 272
[ArrayList - stream]
Start : 1406987110118, End : 1406987110526, Took : 408

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ListAndArray {

    private final int SIZE = 20;
    private final int OUTER_COUNT = 100000;
    
    private ExecutorService executer = Executors.newFixedThreadPool(SIZE);
    
    public static void main(String[] args) {
        ListAndArray instance = new ListAndArray();
        instance.calcListVsArray();
    }
    
    public void calcListVsArray() {
        // initialize
        List list = new ArrayList<>(SIZE);
        for (int i = 0; i < SIZE; i++) {
            list.add(new EventListenerSample());
        }
        EventListenerSample[] array  = list.toArray(new EventListenerSample[list.size()]);

        long startTime;
        long endTime;
        long miliExecTime;
       
        // calc
        System.out.println("[Array - for]");
        startTime = System.currentTimeMillis();
        for (int outer = 0; outer < OUTER_COUNT; outer++) {
            for (int i = 0; i < SIZE; i++) {
                array[i].getLocalDateTime();
            }
        }
        endTime = System.currentTimeMillis();
        miliExecTime = endTime - startTime;
        System.out.printf("Start : %d, End : %d, Took : %d %n", startTime, endTime, miliExecTime);
        
        
        System.out.println("[Array - foreach]");
        startTime = System.currentTimeMillis();
        for (int outer = 0; outer < OUTER_COUNT; outer++) {
            for (EventListenerSample eventListenerSample : array) {
                eventListenerSample.getLocalDateTime();
            }
        }
        endTime = System.currentTimeMillis();
        miliExecTime = endTime - startTime;
        System.out.printf("Start : %d, End : %d, Took : %d %n", startTime, endTime, miliExecTime);
        
        
        System.out.println("[ArrayList - for]");
        startTime = System.currentTimeMillis();
        for (int outer = 0; outer < OUTER_COUNT; outer++) {
            for (int i = 0; i < SIZE; i++) {
                list.get(i).getLocalDateTime();
            }
        }
        endTime = System.currentTimeMillis();
        miliExecTime = endTime - startTime;
        System.out.printf("Start : %d, End : %d, Took : %d %n", startTime, endTime, miliExecTime);
        
        

        System.out.println("[ArrayList - foreach]");
        startTime = System.currentTimeMillis();
        for (int outer = 0; outer < OUTER_COUNT; outer++) {
            for (EventListenerSample eventListenerSample : list) {
                eventListenerSample.getLocalDateTime();
            }
        }
        endTime = System.currentTimeMillis();
        miliExecTime = endTime - startTime;
        System.out.printf("Start : %d, End : %d, Took : %d %n", startTime, endTime, miliExecTime);

        
        System.out.println("[ArrayList - stream]");
        startTime = System.currentTimeMillis();
        for (int outer = 0; outer < OUTER_COUNT; outer++) {
            list.stream().forEach(e -> e.getLocalDateTime());
        }
        endTime = System.currentTimeMillis();
        miliExecTime = endTime - startTime;
        System.out.printf("Start : %d, End : %d, Took : %d %n", startTime, endTime, miliExecTime);
    }

    
    public static class EventListenerSample {
        private Integer integer = Integer.MAX_VALUE - 1;
        private String b = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
        private String c = "ccccccccccccccccccccccccccccccc";
        private LocalDateTime localDateTime = LocalDateTime.now();
        public LocalDateTime getLocalDateTime() {
            return localDateTime;
        }
    }
}