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

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

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

Итак, я хотел спросить, могу ли я сделать Scala компиляцию быстрее и будет когда-либо быстрее, чем javac.

Ответ 1

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

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

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

Ответ 2

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

  • Большие служебные данные запуска

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

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

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

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

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

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

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

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

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

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

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

Ответ 3

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

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

Ответ 4

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

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

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

Ответ 5

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

Подробнее см. "Что лучше всего построит система Scala?".


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

alt text

Но не в прямом Eclipse, хотя Daniel Spiewak упоминает в комментариях:

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


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

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

Ответ 6

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

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

Ответ 7

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

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

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

- Оливер

Ответ 8

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

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

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