Скорость компиляции Java и скорость компиляции Scala

Я некоторое время программировал в Scala, и мне это нравится, но меня раздражает время, затрачиваемое на компиляцию программ. Это похоже на небольшую вещь, но с Java я мог бы внести небольшие изменения в свою программу, нажать кнопку запуска в netbeans, и BOOM, она работает, и со временем компиляция в scala, кажется, требует много времени. Я слышал, что со многими крупными проектами язык сценариев становится очень важным из-за компиляции времени, что я не видел, возникая при использовании Java.

Но я прихожу из Java, который, насколько я понимаю, быстрее, чем любой другой скомпилированный язык, и быстро из-за причин, по которым я перешел на Scala (это очень простой язык).

Поэтому я хотел спросить, могу ли я сделать Scala быстрее скомпилировать и будет быстрее, чем когда бы то ни было javac.

Компилятор Scala более совершенен, чем Java, обеспечивая вывод типа, неявное преобразование и гораздо более мощную систему типов. Эти функции не предоставляются бесплатно, поэтому я бы не ожидал, что scalac будет всегда быстрее, чем javac. Это отражает компромисс между программистом, выполняющим работу, и компилятором, выполняющим эту работу.

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

В своем ответе Мартин Одерски дает гораздо больше подробностей.

Существует два аспекта (отсутствия) скорости для компилятора Scala.

  1. Большие начальные загрузки

    • Сам Scalac состоит из LOT classов, которые должны быть загружены и скомпилированы jit

    • Scalac должен искать путь к classам для всех корневых пакетов и файлов. В зависимости от размера вашего пути к classу это может занять от одной до трех дополнительных секунд.

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

    Ответ Scala на накладные расходы на запуск – либо использовать fsc, либо делать непрерывное построение с помощью sbt. IntelliJ должен быть настроен на использование любого параметра, в противном случае его накладные расходы даже для небольших файлов необоснованно велики.

  2. Медленная скорость компиляции. Scalac управляет около 500 до 1000 линий / сек. Джавак управляет примерно в 10 раз. На это есть несколько причин.

    • Вывод типа является дорогостоящим, в частности, если он подразумевает неявный поиск.

    • Scalac должен дважды проверять тип; один раз согласно правилам Scala и во второй раз после стирания в соответствии с правилами Java.

    • Помимо проверки типов существует около 15 шагов преобразования, чтобы перейти от Scala к Java, что требует времени.

    • Scala обычно генерирует гораздо больше classов на определенный размер файла, чем Java, особенно если функциональные идиомы сильно используются. Генерация байтокода и запись classа требуют времени.

    С другой стороны, 1000-строчная программа Scala может соответствовать программе Java на 2-3K, поэтому некоторая более медленная скорость, когда подсчитывается в строках в секунду, должна быть сбалансирована с большей функциональностью в каждой строке.

    Мы работаем над улучшением скорости (например, путем создания файлов classов параллельно), но нельзя ожидать чудес на этом фронте. Scalac никогда не будет так быстро, как javac. Я считаю, что решение будет заключаться в компиляции серверов, таких как fsc, в сочетании с хорошим анализом зависимостей, чтобы только перекомпилировать только минимальный набор файлов. Мы тоже работаем над этим.

Вы должны знать, что компиляция Scala занимает как минимум на порядок больше, чем Java для компиляции. Причины этого заключаются в следующем:

  1. Соглашения об именах (файл XY.scala не должен содержать class XY и может содержать несколько classов верхнего уровня). Поэтому компилятору может потребоваться найти больше исходных файлов, чтобы найти данный идентификатор classа / признака / объекта.
  2. Implicits – интенсивное использование implicits означает, что компилятор должен искать любое неявное преобразование в рамках данного метода и ранжировать его, чтобы найти «правильный». ( т. е. у компилятора есть расширенный поисковый домен при поиске метода. )
  3. Система типов – система типа scala более сложна, чем Java, и, следовательно, требует больше времени процессора.
  4. Тип вывода – вывод типа вычисляется дорогостоящим и работа, которую javac не нужно делать вообще
  5. scalac включает в себя 8-битный симулятор полностью вооруженной и оперативной боевой станции, с возможностью просмотра с помощью комбинации клавиш CTRL-ALT-F12 во время фазы компиляции GenICode .

Лучший способ сделать Scala – с IDEA и SBT. Настройте элементарный проект SBT (который он сделает для вас, если хотите) и запустите его в автоматическом режиме компиляции (команда ~compile ), и когда вы сохраните проект, SBT перекомпилит его.

Вы также можете использовать подключаемый модуль SBT для IDEA и присоединить SBT-действие к каждой из ваших конфигураций запуска. Модуль SBT также предоставляет интерактивную консоль SBT в IDEA.

В любом случае (SBT работает снаружи или SBT-подключаемый модуль) SBT остается включенным, и поэтому все classы, используемые при построении вашего проекта, «разогреваются», а JIT-ed и начальные накладные расходы устраняются. Кроме того, SBT компилирует только исходные файлы, которые в этом нуждаются. Это, безусловно, самый эффективный способ создания программ Scala.

Последние версии Scala-IDE (Eclipse) намного лучше подходят для инкрементной компиляции.

См. « Что такое лучшая система сборки Scala? » Для получения дополнительной информации.


Другое решение – интегрировать fsc – быстрый автономный компилятор для языка Scala 2 (как показано в этом сообщении в блоге ) в качестве разработчика в вашей среде IDE.

alt text

Но не в прямом Eclipse, хотя, как упоминает Даниил Спивак в комментариях:

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


Наконец, как jackson Дэвис напоминает мне в комментариях:

sbt (Simple build Tool) также включает некоторую «инкрементную» компиляцию (через запущенное выполнение ), хотя она не идеальна , а расширенная инкрементная компиляция находится в работе для предстоящей версии 0.9 sbt.

Используйте fsc – это быстрый компилятор scala, который сидит в качестве фоновой задачи и не требует загрузки все время. Он может повторно использовать предыдущий экземпляр компилятора.

Я не уверен, поддерживает ли плагин scobe Netbeans fsc (документация говорит так), но я не мог заставить его работать. Попробуйте ночные сборки плагина.

Вы можете использовать плагин JRebel, который является бесплатным для Scala. Таким образом, вы можете «развить в отладчике», и JRebel всегда будет перезагружать измененный class на месте.

Я прочитал какое-то заявление где-то самим Мартином Одерским, где он говорит, что поиск implicits (компилятор должен убедиться, что есть не более одного единственного неявного для одного и того же преобразования, чтобы исключить двусмысленности) может удержать компилятор занятым. Поэтому было бы неплохо обращаться с имплицитами с осторожностью.

Если это не должно быть 100% Scala, но и что-то подобное, вы можете попробовать попробовать Kotlin .

– Оливер

Я уверен, что это будет проголосовано, но чрезвычайно быстрый поворот не всегда способствует качеству или производительности.

Потратьте время, чтобы подумать более тщательно и выполнить меньше микроциклов развития. Хороший код Scala более плотный и более существенный (т. Е. Свободный от случайных деталей и сложности). Это требует больше размышлений, и это требует времени (по крайней мере сначала). Вы можете хорошо продвигаться с меньшим количеством циклов кода / теста / отладки, которые индивидуально немного дольше и все еще повышают производительность и качество вашей работы.

Короче: найдите оптимальный рабочий шаблон, который лучше подходит для Scala.

  • почему GCC __builtin_prefetch не улучшает производительность?
  • Когда использовать StringBuilder в Java
  • Быстрое векторное rsqrt и обратное с SSE / AVX в зависимости от точности
  • Doxygen медленный
  • Что быстрее: распределение стека или выделение кучи
  • MyISAM против InnoDB
  • MATLAB parfor медленнее, чем для - что не так?
  • Почему смещение MYSQL выше LIMIT замедляет запрос вниз?
  • Производительность Cellfun и Simple Matlab Loop
  • Рисование поэтапно в UIView (iPhone)
  • Медленная инструкция jmp
  • Давайте будем гением компьютера.