티스토리 뷰

List 클래스 중 무엇이 가장 빠를까?


List 관련 클래스들의 성능을 비교해 보기 위해 아래와 같이 JMH 테스트 코드를 만들었다.

데이터를 담을 때 얼마나 시간 차이가 발생하는지 확인해 보자.


@State(Scope.Thread)
@BenchmarkMode({Mode.AverageTime})
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public class ListAdd {

    int LOOP_COUNT = 1000;

    List arrayList;

    List vector;

    List linkedList;

    @Benchmark
    public void addArrayList() {
        arrayList = new ArrayList<>();
        for (int loop = 0; loop < LOOP_COUNT; loop++) {
            arrayList.add(loop);
        }
    }

    @Benchmark
    public void addVector() {
        vector = new Vector<>();
        for (int loop = 0; loop < LOOP_COUNT; loop++) {
            vector.add(loop);
        }
    }

    @Benchmark
    public void addLinkedList() {
        linkedList = new LinkedList<>();
        for (int loop = 0; loop < LOOP_COUNT; loop++) {
            linkedList.add(loop);
        }
    }

    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(ListAdd.class.getSimpleName())
                .forks(1)
                .build();

        new Runner(opt).run();
    }
}

데이터를 넣는 속도는 어떤 클래스든 큰 차이가 없는 것을 볼 수 있다. 이번에는 데이터를 꺼내는 속도를 확인해 보자.

 


@State(Scope.Thread)
@BenchmarkMode({Mode.AverageTime})
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public class ListGet {

    int LOOP_COUNT = 1000;

    List arrayList;

    List vector;

    List linkedList;

    int result = 0;

    @Setup
    public void setUp() {
        arrayList = new ArrayList<>();
        vector = new Vector<>();
        linkedList = new LinkedList<>();
        for (int loop = 0; loop < LOOP_COUNT; loop++) {
            arrayList.add(loop);
            vector.add(loop);
            linkedList.add(loop);
        }
    }

    @Benchmark
    public void getArrayList() {
        for (int loop = 0; loop < LOOP_COUNT; loop++) {
            result = arrayList.get(loop);
        }
    }

    @Benchmark
    public void getVector() {
        for (int loop = 0; loop < LOOP_COUNT; loop++) {
            result = vector.get(loop);
        }
    }

    @Benchmark
    public void getLinkedList() {
        for (int loop = 0; loop < LOOP_COUNT; loop++) {
            result = linkedList.get(loop);
        }
    }

    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(ListGet.class.getSimpleName())
                .forks(1)
                .build();

        new Runner(opt).run();
    }
}

ArrayList의 속도가 가장 빠르고, Vector와 LinkedList는 속도가 매우 느리다. LinkedList가 터무니없이 느리게 나온 이유는 LinkedList가 Queue 인터페이스를 상속받기 때문이다. 이를 수정하기 위해서는 순차적으로 결과를 받아오는 peek() 메서드를 사용해야 한다.

 


@Benchmark
public void getPeekLinkedList() {
	for (int loop = 0; loop < LOOP_COUNT; loop++) {
    	result = ((LinkedList)linkedList).peek();
    }
}

LinkedList 클래스를 사용할 때는 get 메서드가 아닌 peek()이나 poll() 메서드를 사용해야 한다.

ArrayList와 Vector의 성능 차이가 나는 이유는 ArrayList는 여러 스레드에서 접근할 경우 문제가 발생할 수 있지만, Vector는 여러 스레드에서 접근할 경우를 방지하기 위해서 get() 메서드에 synchronized가 선언되어 있다. 따라서, 성능 저하가 발생할 수밖에 없다.

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함