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

Разработчик

Отправить сообщение
по зомбоящику РосПропаганда ему круглосуточно рассказывает

Вы-то "зомбоящик", насколько я могу судить, не смотрите. А коль так, то откуда вы знаете, что он рассказывает, да ещё и круглосуточно?


не рвал дупу

Что такое "дупа"?


перевода стрелок как дети

Именно это вы и сделали, написав, что пользователи, не восторгающиеся шутками про "глюпи рюзге вспарывает обшивку своего окрабля, азаза", являются ольгинскими (иначе же и быть не может)


Бутина уже заговорила

Да-да, #скоро :)


в России начался настоящий патриотический угар

Судя по использованию слов вроде "дупа" вы живёте не в России. Откуда вы тогда знаете какой угар там начался? ТСН рассказала? ;)


пропогандонш, непричемышей

Ещё раз перечитайте мой предыдущий ответ про предсказуемость.

насколько же вы предсказуемые

ольгинцам

зрителям зомбоящика

РосПропаганда

агент Трамп

Вы-то, я вижу, ни разу не предсказуемы.

Процентов 95 уже через месяц не вспомнят об этом событии, что не отменяет формирования картины мира из подобных «Не более» и «очередной мемасик».

Опять же, если отмотать твиттеры этих самых журналистов до эпизода с плавающей ступенью и сравнить отзывы тогда и сейчас, то видна вполне ясная разница в тональности высказываний и оценок.

Думаю, уместно задать этот вопрос "Роскосмосу". На мой взгляд, мешало наплевательское отношение к своему образу. Мой ответ был не об этом, а об освещении работы космонавтов "непредвзятыми" журналистами. Комментарии вроде


Это, вероятно, является ещё одним первым достижением российской космической программы: космонавт только что обнажил большой нож и проткнул им свой космический корабль.

и


Я отвлеклась на русских, распарывающих свой космический корабль

являются пертосянством чистой воды.

Окажись в этом же положении астронавты НАСА, эти же журналисты захлёбывались бы от хвалебных комментариев и подчёркивали бы важность, нужность и т. д. Но на их месте русские, поэтому объективные западные журналисты натужно шутят и соревнуются в петросянстве.
По поводу двойственного ощущения я ниже оставил комментарий про `SimpleJpaRepository::findAll`.

По поводу дальнейшего использования, я тут посмотрел внутрь org.springframework.data.jpa.repository.support.SimpleJpaRepository, там есть такой метод


public List<T> findAll(Iterable<ID> ids) {

    if (ids == null || !ids.iterator().hasNext()) {
        return Collections.emptyList();
    }

    if (entityInformation.hasCompositeId()) {

        List<T> results = new ArrayList<T>();

        for (ID id : ids) {
            results.add(findOne(id));
        }

        return results;
    }

    ByIdsSpecification<T> specification = new ByIdsSpecification<T>(entityInformation);
    TypedQuery<T> query = getQuery(specification, (Sort) null);

    return query.setParameter(specification.parameter, ids).getResultList();
}

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


Так вот в первом случае возвращается неизменяемый список, а во втором — ArrayList.

Про чистый JDBC не скажу, а Hibernate возвращает пустой список (ЕМНИП, пустой ArrayList).

Тоже вариант, только в этом случае orElseGet не даёт преимущества перед orElse, т. к. Collections.emptyList() возвращает кэшированный список.

В Spring Data запросы вида


@Query("select u from UserEntity u where u.group.id = :groupId")
List<UserEntity> findUsersByGroup(@Param("groupId") Long groupId);

возвращают пустой список (ArrayList) для пустой выборки.

bystr1k прав, этот пример про инварианты. Далеко не все из них обнаруживаются статическими анализаторами.
Разумеется, это всё было найдено и исправлено именно в ходе код вычитки.
Есть крутые доклады Шипилёва и Куксенко, они об общих началах улучшений производительности и о низкоуровневых вещах. Универсальную статью написать сложно, т. к. примеры из этой статьи, основаны на нашем конкретном проекте и совсем не обязательно подойдут для вашего. Как мне кажется, именно поэтому тот же Шипилёв, Черёмин или Вакарт в основном рассказывают об улучшениях кода, привязанного только к JDK как к некой постоянной для многих разработчиков.
Я думал, что исполняться будет ява-кода из `String::equals`, но интринзифицированный метод, насколько я понимаю, исполняет нативный код, оптимизированный под конкретную платформу.
жить, стараясь сделать платформу лучше
Само приложение ещё не перевели на 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);

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

Информация

В рейтинге
1 484-й
Зарегистрирован
Активность