Как стать автором
Обновить
41
0.1
Сергей Цыпанов @tsypanov

Разработчик

Отправить сообщение
жить, стараясь сделать платформу лучше
Само приложение ещё не перевели на JDK 9, так что пока только микробенчмарки )
Его проверил самым первым, там итератор всегда скаляризуется.

Проверил с помощью -prof gc, действительно, даже на восьмёрке итератор не создаётся: gc.alloc.rate.norm постоянно около 0. По времени счётный перебор конечно же быстрее, хотя и ненамного.


А вот для Collection.containsAll() скаляризация срабатывает только на небольших объёмах:


@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Fork(jvmArgsAppend = {"-XX:+UseParallelGC", "-Xms1g", "-Xmx1g"})
public class AllMatchVsContainsAllBenchmark {

    @Benchmark
    public boolean collectionContainsAll(Data data) {
        return data.original.containsAll(data.half);
    }

    @State(Scope.Thread)
    public static class Data {

        @Param({"10", "100", "1000"})
        int count;

        @Param({"ArrayList", "HashSet"})
        String collectionType;

        Collection<Integer> half;
        Collection<Integer> original;

        @Setup
        public void setup() {
            if ("ArrayList".equals(collectionType)) {
                original = IntStream.range(0, count).boxed().collect(toCollection(ArrayList::new));
                half = new HashSet<>(halfOfCollection(original));
            } else {
                original = IntStream.range(0, count).boxed().collect(toCollection(HashSet::new));
                half = new HashSet<>(halfOfCollection(original));
            }
        }

        private List<Integer> halfOfCollection(Collection<Integer> original) {
            int newLength = original.size() / 2;
            Integer[] integers = copyOf(original.toArray(new Integer[0]), newLength);
            return asList(integers);
        }
    }
}

даёт


Benchmark           (collectionType)  (count)    Score     Error  Units
gc.alloc.rate.norm         ArrayList       10   ≈ 10⁻⁵             B/op
gc.alloc.rate.norm         ArrayList      100    0,001 ±   0,001   B/op
gc.alloc.rate.norm         ArrayList     1000   40,066 ±   0,003   B/op
gc.alloc.rate.norm           HashSet       10   ≈ 10⁻⁴             B/op
gc.alloc.rate.norm           HashSet      100   ≈ 10⁻⁴             B/op
gc.alloc.rate.norm           HashSet     1000   20,004 ±   6,817   B/op

Верно, в документации сказано:


It indicates that an annotated method may be (but is not guaranteed to be) intrinsified by the HotSpot VM. A method is intrinsified if the HotSpot VM replaces the annotated method with hand-written assembly and/or hand-written compiler IR — a compiler intrinsic — to improve performance.

Думаю, вместо "создавать для них высокопроизводительный машинный код" мне стоило написать "подменять их реализацию высокопроизводительным машинным кодом". Кстати, интересно было бы узнать, в каких условиях интринсификация не срабатывает.


В Arrays.asList много чего не реализовано, например hashCode(): в текущей реализации вызывается метод абстрактного списка, использующий итератор, хотя можно было бы написать


@Override
public int hashCode() {
  return Arrays.hashCode(a);

и обойтись без перебора итератором.

Спасибо )) несу высокопроизводительную яву в массы )
ЕМНИП, в старых версиях у `ArrayList`-а не было собственной реализации подсписка и итератора.
Спасибо, поменял.
Спецификация требует, чтобы возвращалась именно копия массива.
12 ...
47

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность