Проверил с помощью -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);
}
}
}
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);
Проверил с помощью
-prof gc
, действительно, даже на восьмёрке итератор не создаётся:gc.alloc.rate.norm
постоянно около 0. По времени счётный перебор конечно же быстрее, хотя и ненамного.А вот для
Collection.containsAll()
скаляризация срабатывает только на небольших объёмах:даёт
Верно, в документации сказано:
Думаю, вместо "создавать для них высокопроизводительный машинный код" мне стоило написать "подменять их реализацию высокопроизводительным машинным кодом". Кстати, интересно было бы узнать, в каких условиях интринсификация не срабатывает.
В Arrays.asList много чего не реализовано, например hashCode(): в текущей реализации вызывается метод абстрактного списка, использующий итератор, хотя можно было бы написать
и обойтись без перебора итератором.