Швидкість компіляції Java проти швидкості компіляції Scala


101

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

Але я родом з Java, яка, як я розумію, швидша за будь-яку іншу мову, що склалася, і швидка через причини, що я перейшов на Scala (Це дуже проста мова).

Тож я хотів запитати, чи можу я змусити Scala компілювати швидше і чи буде Scalac коли-небудь таким швидким, як javac.


Схоже, деякі користувачі згодні з вами;) twitter.com/etorreborre/status/21286172202
VonC

Перехід компілюється швидше, ніж Java. Швидше, що щось говорить.
Даніель К. Собрал

Ахаха, в моєму випадку потрібно кілька хвилин для складання середньої шкали з кількома гончаними LOC, fsc трохи швидше.
Джеріхо

Відповіді:


57

Компілятор Scala є більш досконалим, ніж Java, що забезпечує висновок про тип, неявне перетворення та набагато більш потужну систему типу. Ці функції не приходять безкоштовно, тому я не очікував, що масштаб колись буде таким швидким, як javac. Це відображає компроміс між програмістом, який виконує роботу, і компілятором, який виконує роботу.

Однак, час збирання вже помітно покращився, переходячи від Scala 2.7 до Scala 2.8, і я очікую, що поліпшення триватимуть зараз, коли пил осіла на 2.8. Ця сторінка документує деякі поточні зусилля та ідеї щодо підвищення продуктивності компілятора Scala.

У своїй відповіді Мартін Одерський надає набагато більше деталей.


1
Чи не більше цієї сторінки ( lamp.epfl.ch/~magarcia/ScalaCompilerCornerReloaded )?
VonC

Я перейшов з сітчастого на мурашник + jedit (я знаю, що знаю, мураш призначений для печерних людей, але я буду еволюціонувати самостійно), щоб я міг використовувати fsc. Але мені було цікаво, як швидкість компіляції Clojure порівнюється зі Scala? Здається, у Scala багато особливостей, але я думаю, що синтаксис набагато простіше розібратися.
користувач405163

1
Ми ніби не виходимо з теми тут, але компілятор Clojure швидко зростає (набагато швидше, ніж javac на еквівалентних джерелах). Ви маєте рацію, що це дійсно проста мова, і вона не має будь-якої системи статичного типу, що дуже допомагає.
Даніель Шпієк

458

Для компілятора Scala є два аспекти щодо (недостатньої) швидкості.

  1. Більший запуск накладних витрат

    • Сам Scalac складається з багато класів, які потрібно завантажувати і компілювати jit

    • Scalac має шукати шлях для всіх кореневих пакетів та файлів. Залежно від розміру вашого курсу, це може зайняти від однієї до трьох додаткових секунд.

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

    Відповідь Scala на запуск накладних витрат - або використовувати fsc, або робити безперервне будівництво з sbt. IntelliJ потрібно налаштувати так, щоб використовувати будь-який варіант, інакше його накладні витрати навіть для невеликих файлів невиправдано великі.

  2. Повільна швидкість компіляції. Scalac управляє приблизно від 500 до 1000 ліній / сек. Яваку вдається приблизно в 10 разів. Для цього є кілька причин.

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

    • Scalac повинен двічі перевірити тип; один раз за правилами Scala і другий раз після стирання за правилами Java.

    • Окрім перевірки типів, існує ще близько 15 кроків трансформації, щоб пройти від Scala до Java, на що всі потребують часу.

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

    З іншого боку, програма Scala на 1000 ліній може відповідати програмі Java на 2-3 К рядків, тому деяка більш повільна швидкість при підрахунку рядків в секунду повинна врівноважуватися проти більшої функціональності на рядок.

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


1
Про накладні витрати через завантаження класу: чи допоможе дострокове компіляція до нативного коду за допомогою GCJ або Mono?
Механічний равлик

15
Що робити, якщо Scala були переписані на C ++? : o)
marcus

Чи не буде користі використовувати інструкцію викликаного динамічного байт-коду?
Роб Грант

40

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

  1. Конвенції іменування (файловий XY.scalaфайл не повинен містити клас, який називається, XYі може містити кілька класів верхнього рівня). Тому компілятору, можливо, доведеться шукати більше вихідних файлів, щоб знайти заданий ідентифікатор класу / ознаки / об'єкта.
  2. Імпліцити - велике використання імпліцитів означає, що компілятору необхідно шукати будь-яке неявне перетворення за певним методом та класифікувати їх, щоб знайти "правильний". ( тобто компілятор має значне збільшення доменного пошуку при пошуку методу. )
  3. Система типу - система типу scala набагато складніше, ніж у Java, а значить, займає більше часу в процесорі.
  4. Тип умовиводу - висновок типу обчислювально дорогий і робота, яку javacвзагалі не потрібно виконувати
  5. scalacвключає 8-бітний тренажер повністю озброєної та оперативної бойової станції, який можна переглянути, використовуючи чарівну комбінацію клавіш CTRL-ALT-F12 під час фази компіляції GenICode .

3
@obox_lakes, ненависть чіплятися, але Java робить необхідність зробити висновок типу для параметрезованих методів , int a<T>(T a) {}а потім a(pls_infer_my_type). james-iry.blogspot.com/2009/04/…
Елазар Лейбович

13
@Elazar - так, я знаю. Але відверто смішно, поруч зі шкалою, називати це "типовим висновком"!
oxbow_lakes


19

Найкращий спосіб зробити Scala - це IDEA та SBT. Створіть елементарний проект SBT (який він зробить для вас, якщо вам подобається) та запустіть його в автоматичному режимі компіляції (команди ~compile), і коли ви збережете проект, SBT перекомпілює його.

Ви також можете використовувати плагін SBT для IDEA та додавати дії SBT до кожної із своїх конфігурацій запуску. Плагін SBT також дає вам інтерактивну консоль SBT в межах IDEA.

У будь-якому випадку (SBT працює зовні або плагін SBT), SBT залишається запущеним, і, таким чином, всі класи, які використовуються для побудови вашого проекту, «прогріваються», а JIT-ed та виключаються накладні витрати. Крім того, SBT компілює лише вихідні файли, які потребують цього. Це, безумовно, найефективніший спосіб побудови програм Scala.


9

Останні версії Scala-IDE (Eclipse) значно краще керують поступовим складанням.

Докладніше див. У розділі " Яка найкраща система побудови Scala? "


Іншим рішенням є інтеграція fsc - швидкого офлайн-компілятора для мови Scala 2 - (як показано в цій публікації блогу ) як конструктора у вашому IDE.

alt текст

Але не безпосередньо у Eclipse, як, як згадує Данило Співак у коментарях:

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


Нарешті, як нагадає мені Джексон Девіс у коментарях:

sbt (Simple Build Tool) також включає якусь "поступову" компіляцію (за допомогою запущеного виконання ), хоча вона не є ідеальною , і розширена інкрементальна компіляція працює в майбутньому версії 0,9 sbt.


2
sbt також можна робити додаткові компіляції
Джексон Девіс,

@Jackson: спрацьовано виконання, так! Я включив це у свою відповідь.
VonC

2
Ви не повинні використовувати FSC в межах Eclipse безпосередньо, хоча б тому, що Eclipse вже використовує FSC під поверхнею. FSC - це в основному тонкий шар поверх резидентного компілятора, який є саме механізмом, який Eclipse використовує для складання проектів Scala.
Даніель Шпієк

1
FSC розшифровується як компілятор Fast Scala - не швидкий компілятор Java
Ben McCann

@BenMcCann: на жаль. Правильно. Я зафіксував відповідь.
VonC

6

Використовуйте fsc - це швидкий компілятор масштабування, який працює як фонове завдання і не потребує завантаження весь час. Він може повторно використовувати попередній екземпляр компілятора.

Я не впевнений, чи підтримує плагін Netbeans scala підтримку fsc (документація так говорить), але я не міг змусити його працювати. Спробуйте щорічно створювати плагін.


1
У плагіні IntelliJ IDEA Scala також є можливість використовувати fsc
Aaron Novstrup

1
@anovstrup: так, але іноді виходить з ладу.
Денис Тульський

4

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

Я десь прочитав десь заяву самого Мартіна Одерського, де він говорить, що пошук імпліцитів (компілятор повинен переконатися, що не більше ніж один єдиний неявний для одного і того ж перетворення, щоб виключити двозначності) може тримати компілятора зайнятим. Тому може бути гарною ідеєю обережно поводитися з наслідками.

Якщо це не має бути 100% Scala, але також щось подібне, ви можете спробувати Котліна .

- Олівер


2

Я впевнений, що це буде знижено, але надзвичайно швидкий поворот не завжди сприяє якості чи продуктивності.

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

Коротше кажучи: шукайте оптимальну схему роботи, яка краще відповідає Scala.


3
Я погоджуюся, що не дуже важливо мати швидкий цикл повороту. Але це не боляче, чи не так?
Елазар Лейбович

27
Я не збираюся проголосувати, але сказати, що ви повинні налаштувати свою схему роботи під обмеження вашого інструменту (низька швидкість компілятора), а не намагатися вдосконалити інструмент, не є гарним аргументом. Особливо здатність робити швидкі тестові цикли дуже цінна (навіть якщо це не замінює необхідності глибокого мислення, такого, що, мабуть, найкраще робити далеко від клавіатури, але це прекрасно доповнює).
Тило

9
Я думаю, що більшість моєї продуктивності насправді втрачається над передумовою перед запуском. Я часто опиняюсь на деяке рівняння протягом тривалих періодів, намагаючись помітити, що на мене чекає колись потенційний підводний камінь, поки я думаю: "Просто запустіть його!" в потилиці. І досить впевнено, коли я запускаю програму, я дізнаюся набагато більше, ніж, мабуть, мав би ще годину чи дві медитації. Медитація хороша, але я вважаю, що я мав дуже оптимальне використання поступового складання / медитації з java.
user405163

2
Це також схоже на те, що Шекспір ​​не повинен використовувати перевірку орфографії, а натомість дужче думати про те, що він хоче сказати. Автоматизована перевірка орфографії допомагає при зовсім іншому наборі проблем.
Тіло
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.