Хоча відповіді, що пропонують використовувати ArrayList, мають сенс у більшості сценаріїв, насправді на питання щодо відносної продуктивності насправді не було дано відповідей.
З масивом можна виконати кілька речей:
- створити його
- встановити елемент
- отримати предмет
- клонувати / копіювати
Загальний висновок
Хоча операції отримання та встановлення дещо повільніші на ArrayList (відповідно 1 та 3 наносекунда за виклик на моїй машині), використання ArrayList проти масиву для будь-якого неінтенсивного використання дуже мало. Однак слід пам’ятати про кілька речей:
- зміни розміру операцій зі списку (під час дзвінка
list.add(...)
) є дорогими, і потрібно намагатися встановити початкову потужність на достатньому рівні, коли це можливо (зауважте, що ця ж проблема виникає при використанні масиву)
- при роботі з примітивами, масиви можуть бути значно швидшими, оскільки вони дозволять уникнути багатьох перетворень боксу / розпакування
- додаток, який отримує / встановлює значення в ArrayList (не дуже часто!), може побачити збільшення продуктивності більше 25%, перейшовши на масив
Детальні результати
Ось результати, які я виміряв для цих трьох операцій, використовуючи бібліотеку jmh бенчмаркінгу (разів у наносекундах) з JDK 7 на стандартній настільній машині x86. Зауважте, що тести ArrayList ніколи не змінюються, щоб переконатися, що результати порівнянні. Код орієнтиру доступний тут .
Створення масиву / ArrayList
Я провів 4 тести, виконавши такі твердження:
- createArray1:
Integer[] array = new Integer[1];
- createList1:
List<Integer> list = new ArrayList<> (1);
- createArray10000:
Integer[] array = new Integer[10000];
- createList10000:
List<Integer> list = new ArrayList<> (10000);
Результати (у наносекундах за дзвінок, 95% впевненості):
a.p.g.a.ArrayVsList.CreateArray1 [10.933, 11.097]
a.p.g.a.ArrayVsList.CreateList1 [10.799, 11.046]
a.p.g.a.ArrayVsList.CreateArray10000 [394.899, 404.034]
a.p.g.a.ArrayVsList.CreateList10000 [396.706, 401.266]
Висновок: помітної різниці немає .
отримати операції
Я провів 2 тести, виконавши такі твердження:
- getList:
return list.get(0);
- getArray:
return array[0];
Результати (у наносекундах за дзвінок, 95% впевненості):
a.p.g.a.ArrayVsList.getArray [2.958, 2.984]
a.p.g.a.ArrayVsList.getList [3.841, 3.874]
Висновок: отримання з масиву приблизно на 25% швидше ніж отримання з ArrayList, хоча різниця полягає лише в порядку однієї наносекунди.
встановити операції
Я провів 2 тести, виконавши такі твердження:
- setList:
list.set(0, value);
- setArray:
array[0] = value;
Результати (у наносекундах за дзвінок):
a.p.g.a.ArrayVsList.setArray [4.201, 4.236]
a.p.g.a.ArrayVsList.setList [6.783, 6.877]
Висновок: задані операції на масивах приблизно на 40% швидші, ніж у списках, але, що стосується отримання, кожна операція набору займає кілька наносекунд - так, щоб різниця досягла 1 секунди, потрібно було б встановити елементи у списку / масиві сотні мільйонів разів!
клон / копія
Конструктор копіювання Делегати ArrayList, щоб Arrays.copyOf
таким чином продуктивність є ідентичною копією масиву (копіювання масиву з допомогою clone
, Arrays.copyOf
або System.arrayCopy
не має жодної істотної відмінності точки зору продуктивності ).