Бенчмарки, связанные с enterprise-технологиями (Spring, Hibernate), пока реализованы только для JDK8 (ветка master). Ветка master-java-9 включает бенчмарки, использующие только Java Core. Ветка настроена на JDK9. Для замеров на JDK10/11 можно использовать ветку master-java-9. Всё, что нужно сделать - выставить для проекта нужный JDK.
Показывает разницу между проходом по "голому" массиву
Integer[] array = holder.array;
for (Integer integer : array) {
bh.consume(integer);
}
и проходом по массиву, завёрнутому в Arrays.asList
List<Integer> integers = Arrays.asList(array);
for (Integer integer : integers) {
bh.consume(integer);
}
Итоги замеров см. в results/ArrayVsAsListIterationBenchmark.md
Также см. IDEA-184240 Unnecessary array-to-collection wrapping should be detected
Показывает разницу между
ArrayList.toArray(new T[0])
и
ArrayList.subList(0, size()).toArray(new T[0])
Несмотря на равный объём перемещаемых данных, производительность второго способа значительно хуже.
См. JDK-8196207 Inefficient ArrayList.subList().toArray()
Показывает разницу между тремя способами заполнения коллекции:
1.
Collection<Integer> newCollection = new ArrayList<>();
for (Integer item : items) {
newCollection.add(item);
}
2.
Collection<Integer> newCollection = new ArrayList<>();
newCollection.addAll(items);
3.
Collection<Integer> newCollection = new ArrayList(items);
См. IDEA-165942 Inspection to replace method call in a loop with bulk operation
Показывает разницу между
Arrays.asList(array).subList(0, to).toArray(new Integer[0])
и
Arrays.copyOf(array, to);
Итоги замеров см. в results/SubArrayBenchmark.md
Также см. IDEA-182206 Simplification for Arrays.asList().sublist().toArray()
Показывает разницу между
public long createCashFlow(CashFlowDto dto) {
boolean isInvalid = dto.getNumber() % 2 != 0;
if (isInvalid) {
return -1L;
}
return cashFlowServiceLocal.createCashFlow(dto);
}
и
@Transactional(readOnly = true)
public long createCashFlow(CashFlowDto dto) {
boolean isInvalid = dto.getNumber() % 2 != 0;
if (isInvalid) {
return -1L;
}
return cashFlowServiceLocal.createCashFlow(dto);
}
Иными словами, показывает стоимость "холостой" транзакции.
Показывает разницу между тремя способами перебора элементов стрима
1)
Iterator<String> iterator = items.stream()
.map(Object::toString)
.collect(toList())//todo add case for toSet()
.iterator();
while (iterator.hasNext())
bh.consume(iterator.next());
2)
Iterator<String> iterator = items.stream()
.map(Object::toString)
.iterator();
while (iterator.hasNext())
bh.consume(iterator.next());
3)
items.stream()
.map(Object::toString)
.forEach(bh::consume);
Итоги замеров см. в results/iteratorFromStream.txt
Показывает разницу между
set.stream().allMatch(data.collection::contains);
и
collection.containsAll(data.set);
Итоги замеров см. в results/ArrayVsAsListIterationBenchmark.md
Также см. IDEA-187623 Arrays.stream.anyMatch can be simplified
Бенчмарк, показывающий разницу между вызовом JpaRepository.findOne
в цикле и единичным вызовом JpaRepository.findAll
См. IDEA-165730 Warn about inefficient usages of JpaRepository
Показывает разницу между удалением из ArrayList-а
тремя способами
- прямой проход (наименее производительный)
for (int i = from; i < to; i++) {
arrayList.remove(from);
}
- обратный проход (движение в сторону меньших индексов)
for (int i = to - 1; i >= from; i--) {
arrayList.remove(i);
}
- обратный проход с разворотом списка (позволяет сохранить порядок удаления и даёт доступ к порядковому номеру удаляемого элемента)
public removeInReverseOrder() {
reverse(arrayList);
for (int i = to - 1; i >= from; i--) {
arrayList.remove(i);
}
}
private static <T> void reverse(ArrayList<T> list) {
int i = 0;
int j = list.size() - 1;
while (i < j) {
swap(list, i, j);
i++;
j--;
}
}
private static <T> void swap(ArrayList<T> list, int i, int j) {
T tmp = list.get(i);
list.set(i, list.get(j));
list.set(j, tmp);
}
- очистка подсписка (наиболее производительный)
arrayList.subList(from, to).clear();
См. IDEA-177466 Detect list.remove(int index) called in a loop
Показывает разницу между преобразованием в строку java.util.Date
и java.time.LocalDate
,
а также их сранвнение с промежуточным способом: превращение java.util.Date
в java.time.LocalDate
и преобразование java.time.LocalDate
с помощью java.time.format.DateTimeFormatter
Показывает проседание кода, использующего обёртку там, где достаточно обойтись простым типом
Long accumulator = 0L;
for (Long aLong : data.longs) {
accumulator += aLong == null ? 0 : aLong;
}
return accumulator;
в цикле проиходит создание ненужных сущностей java.lang.Long
при вычислении суммы.
Лучше так:
long accumulator = 0L;
for (Long aLong : data.longs) {
accumulator += aLong == null ? 0 : aLong;
}
return accumulator;
Итоги замеров см. в results/BoxingBenchmark.md
Также см. IDEA-189336 New inspection 'Wrapper type may be primitive'
Показывает разницу между вызовом
Arrays.asList().stream().anyMatch()
и
Arrays.asList().contains();
Итоги замеров см. в results/AnyMatchVsContainsAllBenchmark.md.md