Подтвердить что ты не робот

Устранение медленной компиляции

Что делать, чтобы исследовать и устранять проблему с медленной компиляцией?

Мой проект имеет около 100 классов и занимает более 45 секунд для компиляции, что кажется мне очень медленным. В качестве ссылки у меня есть другой проект с 50 классами, который скомпилируется за 3 секунды.

пс:

  • Я использую maven как инструмент построения. Требуется maven ~ 50 секунд для компиляции (mvn clean compile), из которых 45 секунд потрачены на запуск javac (подтвержденный запуском с опцией -X).
  • увеличение объема памяти не помогло (-Xms500m)
  • Я могу дать больше информации о моем проекте, но он довольно стандартный, поэтому я не уверен, какая информация релевантна.

UPDATE

Благодаря идее Тагира мне удалось найти одного из виновников. Этот класс добавляет 20 секунд к времени компиляции:

import org.jooq.DSLContext;
import org.jooq.Field;
import static org.jooq.impl.DSL.field;
import static org.jooq.impl.DSL.round;
import static org.jooq.impl.DSL.sum;


class Test {
  static Object fast(DSLContext sql) {
    Field<Double> a = field("a").cast(Double.class);
    return sql.select()
            .having(round(sum(a).cast(Double.class), 2).ne(0d));
  }
  static Object slow(DSLContext sql) {
    return sql.select()
            .having(round(sum(field("a").cast(Double.class)).cast(Double.class), 2).ne(0d));
  }
}

Если метод slow закомментирован, время компиляции возвращается к нормальному.

4b9b3361

Ответ 1

Устранение неполадок - общий подход

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

Затем вы можете удалить все классы в пакете и добавить их один за другим, что должно помочь вам найти классы, которые вызывают проблему.

Затем вы можете удалить все методы из каждого из этих классов и добавить их один за другим до тех пор, пока не увидите увеличение времени компиляции (вы можете сэкономить время только перекомпилировать, что один класс).

Конкретная причина

В этом случае кажется, что основная причина - ошибка в javac, поэтому я подал отчет об ошибке который был помечен как дубликат "JEP 215: Многоуровневое атрибутирование для javac" с целью, которая будет исправлена ​​на Java 9.

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

Ответ 2

Не так хорошо известна функция Java 8: Обобщенный вывод типа цели.

Пока он позволяет писать более четкий код, для этого требуется больше работы для Javac. Иногда это приводит к экспоненциальной сложности проблемы вывода типа. Это известная проблема, но, к сожалению, еще не решена - см. JDK-8055984, JDK-8067767.

Обходной путь заключается в компиляции на уровне совместимости Java 7: javac -source 7 или просто для использования более простых конструкций.

Ответ 3

С этим связано несколько обсуждений. Добавьте эти ссылки в случае, если кто-то еще наткнется на этот пост.

Начальное обсуждение:

В моем случае я старался как можно больше использовать автоматически сгенерированный код. В качестве альтернативы вы можете попробовать предложение, которое Лукас упоминает в этой статье StackOverflow, связанной выше.