前書き
徹底攻略Java SE 8 Gold問題集を読みながらJavaGoldの勉強をしていたところ、以下のような記述を見つけた。
ArrayDeque<E>クラスは、内部で配列を使用したDequeインタフェースの実装 であり、以下のような特徴があります。
・FIFO(キュー)として用いる場合には、LinkedList<E>クラスを使用するよりも高速である
・FILO(スタック)として用いる場合には、java.util.Stack<E>クラスを使用するよりも高速である
ArrayDeque<E>クラスやLinkedList<E>クラスは スレッド・セーフではない ため、マルチスレッドのアプリケーションで使用する場合には、スレッド・セーフに設計されているStack<E>クラスが安全です。
なるほど、ArrayDequeが高速で、マルチスレッド環境で利用する場合はStackが速いのか。
ん、なんかConcurrentLinkedDeque<E>ってやつがあるんだけどこれ何?
スレッドセーフなやつっぽい?
じゃあStackとConcurrentLinkedDequeってどっちが速いの?
とか思ってちょっと検索したら何も出て来なかったので実際に色々叩いてみました。
最初に結果
クラス | 1億回の出し入れにかかった時間(ミリ秒) |
---|---|
ArrayDeque<E> | 114 |
LinkedList<E> | 442 |
Stack<E> | 1659 |
ConcurrentLinkedDeque<E> | 3961 |
調べ方
結構適当です。以下のようなプログラムをコメントアウトしたり外したりしながら叩きました。
public static void main(String[] args) {
LocalDateTime startTime = LocalDateTime.now();
System.out.println("start " + startTime);
int roopcount = 100000000;
/*
Deque<String> ll = new LinkedList<>();
//Deque<String> ll = new ArrayDeque<>();
//Deque<String> ll = new ConcurrentLinkedDeque<>();
for(int i = 0; i < roopcount; i++) {
ll.addLast("test");
ll.removeLast();
}
*/
Stack<String> st = new Stack<>();
for(int i = 0; i < roopcount; i++) {
st.add("test");
st.pop();
}
LocalDateTime endTime = LocalDateTime.now();
System.out.println("\r\nend " + endTime);
System.out.println("経過ミリ秒 " + ChronoUnit.MILLIS.between(startTime, endTime));
}
結論
確かにLinkedListよりもArrayDequeの方が速いので、Dequeとして使う場合はArrayDequeの方がよさそうです。
マルチスレッド環境で利用する場合、Stackの機能で充分な場合はStackを利用し、Dequeの機能が必要である場合はConcurrentLinkedDequeを利用するといった使い分けになるでしょうか。
誰かの参考になれば幸いです。