два очевидных варианта является ArrayList
и LinkedList
. A LinkedList
выглядит немного медленнее, чем ArrayList
. Вот мой бенчмаркинг код:
import java.util.*;
public class ListTest {
private static final int N = 50000;
private static final float NANO_TO_MILLI = 1.0e-6f;
public static void main(String[] args) {
String[] strings = new String[N];
for (int i = 0; i < N; ++i) {
strings[i] = Integer.toString(i);
}
System.out.print("ArrayList: ");
benchmark(strings, new ArrayList<String>());
System.out.print("LinkedList: ");
benchmark(strings, new LinkedList<String>());
}
private static void benchmark(String[] strings, List<String> list) {
// measure how long it takes to add the strings
long start = System.nanoTime();
for (String s : strings) {
list.add(s);
}
long addTime = System.nanoTime() - start;
// measure how long it takes to iterate the list
start = System.nanoTime();
int i = 0;
for (String s : list) {
++i;
}
long iterateTime = System.nanoTime() - start;
// report the results
System.out.println(String.format("add: %.2fms; iterate: %.2fms (%d strings)",
addTime * NANO_TO_MILLI,
iterateTime * NANO_TO_MILLI,
i));
}
}
И здесь результаты типичного прогона:
ArrayList: добавить: 5.52ms; итерация: 7,66 мс (50000 строк)
LinkedList: add: 7.79ms; итерация: 8.32ms (50000 строк)
Это было на компьютере с процессором Intel Core2 Quad Q6600 с тактовой частотой 2,4 ГГц.
Обратите внимание, что это измеряет общее время. Он не измеряет изменение времени добавления отдельных строк, что я ожидал бы выше для ArrayList
, чем для LinkedList
, из-за необходимости перераспределения внутреннего массива.
EDIT: Если я изменить main
повторить тест пять раз подряд, с вызовом System.gc()
после каждого вызова benchmark
, то я получить некоторые интересные результаты:
ArrayList: добавить: 5.84ms ; итерация: 7,88 мс (50000 строк)
LinkedList: add: 7.24ms; итерация: 8,27 мс (50000 строк)
ArrayList: add: 0.45ms; итерация: 0,60 мс (50000 строк)
LinkedList: add: 0.84ms; итерация: 5,35 мс (50000 строк)
ArrayList: add: 0.52ms; итерация: 0,72 мс (50000 строк)
LinkedList: add: 0.81ms; итерация: 5,57 мс (50000 строк)
ArrayList: add: 3.77ms; итерация: 0,71 мс (50000 строк)
LinkedList: add: 3.35ms; итерация: 0,93 мс (50000 строк)
ArrayList: add: 3.39ms; итерация: 0,87 мс (50000 строк)
LinkedList: add: 3.38ms; итерация: 0,86 мс (50000 строк)
Возможно, это связано с кэшированием процессором. Обратите внимание: LinkedList
может быть немного быстрее (например, последним для итераций) для добавления строк, хотя он также может быть намного медленнее. Итерация также может быть значительно медленнее для LinkedList
, также, вероятно, из-за отсутствия локальности.
Какие варианты вы считаете? –
Сколько (порядка величины) строк в среднем ожидается? Известно ли число во время выполнения перед чтением? Мы говорим о жестком приложении реального времени или вы просто оптимизируете преждевременно? Я могу дать вам очень разные ответы (ну, образованные догадки) в зависимости от ответа на каждый из этих вопросов, и есть, вероятно, больше факторов. Кроме того, единственный универсальный ответ на вопрос «что быстрее?» это «попробуйте и профиль!». – delnan
@ delnan После некоторого тестирования кажется, что ArrayList быстрее. Если есть разные возможности, вы можете сказать мне, когда каждый из них быстрее. – w1th0utnam3