Долго ли компилируется в прошлом?

38

Существует множество военных историй о том, сколько времени может занять компиляция. Даже xkcd упомянул об этом.

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

Разве я не был подвержен проектам с длительным временем компиляции? Является ли это пережитком прошлого, которое больше не происходит в наши дни? Почему компиляция занимает так много времени?

Thunderforge
источник
31
Попробуйте скомпилировать хром.
UldisK
2
Возьмите копию ядра Linux. Сделайте полную сборку. Посмотреть на себя. Или Spring из исходного кода, если вы Java-кодер. Как есть, у этого вопроса есть несколько ответов, которые отвечают на вопрос, как если бы это был опрос (ответы типа «Я сделал 30-минутные компиляции ...»), который указывает на то, что сам вопрос не подходит ,
Недавний крупный проект занял у меня 40 минут на компиляцию (40 000 файлов исходного кода, компилируемых с Maven). Обходной путь должен парализовать компиляцию на многих процессорных ядрах.
Никлас Розенкранц
2
Подберите исходный дистрибутив Linux (gentoo, LFS, ...), затем потратьте дни на компиляцию каждого устанавливаемого программного обеспечения.
Василий Старынкевич,
6
определить долго ... Некоторым детям, только что вышедшим из школы, 1 минута может показаться длинной, старику, который несколько десятилетий пробыл в окопах, не поднимайте брови.
jwenting

Ответы:

48

Компиляция может занять некоторое время, особенно для больших проектов, написанных на таких языках, как C, C ++ или Scala. Компиляция частей в фоновом режиме может сократить время компиляции, но иногда вам приходится делать новую компиляцию. Факторы, которые могут привести к увеличению времени компиляции, включают в себя:

  • Большой размер кода, очевидно. Большие проекты будут содержать сотни тысяч строк кода.

  • #includeДиректива препроцессора C , которая эффективно приводит к тому, что один и тот же код компилируется сотни раз. У системы макросов есть похожие проблемы, так как она работает на уровне текста. Препроцессор действительно увеличивает размер кода, который фактически передается компилятору. Просмотр файла после предварительной обработки (например, через gcc -E) должен открыть ваши глаза.

  • Шаблоны C ++ полны по Тьюрингу, что означает, что теоретически вы можете выполнять произвольные вычисления во время компиляции. Никто на самом деле не хочет этого делать, но даже многие простые случаи сводятся к тому, чтобы потратить некоторое время на специализацию шаблонов.

  • Scala - довольно молодой язык, и компилятор ужасно неоптимизирован. В настоящее время компилятор использует очень большое количество этапов компиляции (C разработан так, чтобы требовать только два этапа компиляции). Проверка типов является одним из таких этапов, и может занять некоторое время из-за сложной системы типов, представленной языком.

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

Амон
источник
14
На самом деле, система типов в Scala завершена по Тьюрингу, поэтому проверка типов может занимать бесконечное количество времени, и компилятор не может определить это.
Йорг Миттаг,
7
Не забывайте оптимизацию. Много оптимизаций, которые (например) компилятор C / C ++ будет делать, очень дороги (например, настолько дороги, что JIT не может позволить себе сделать их вообще). В худшем случае большинство цепочек инструментов теперь поддерживают оптимизацию всей программы, что, как известно, значительно увеличивает время сборки.
Брендан
Я принял этот ответ, потому что вы указали на ряд вещей, которые я не рассматривал, в частности, компиляцию всего этого, а не компиляцию по частям, и тот факт, что тестовые наборы могут быть включены в это время «компиляции».
Громовой
1
не только наборы тестов - анализ покрытия кода, автоматическая упаковка, автоматизированное развертывание в тестовой системе; В наши дни в интегрированную систему сборки есть много вещей. И если вы находитесь в режиме ожидания до тех пор, пока не доберетесь до среды разработки или тестирования, у вас наверняка есть время для небольшого поединка на стуле.
CorsiKa
1
Отличный ответ, я бы просто отметил, что разброс возможных времен компиляции может быть намного больше. Я работал над проектами, где полная компиляция могла занять два-три дня (да, это было ужасно!), И я предполагаю, что там есть худшие нарушители.
Рой Т.
17

Это ни в коем случае не пережиток прошлого. Один из проектов, над которым я работаю, требует 45 минут для чистой сборки с нуля. Помимо нашего собственного кода, мы также должны извлечь и собрать исходный код из нескольких больших библиотек C и C ++ из внешних репозиториев. Компиляция и компоновка кода C и C ++ требует больших вычислительных ресурсов. Как вы указали, Python обычно реализуется как интерпретируемый язык, а Java обычно использует JIT (Just in Time) компилятор, поэтому ваши проекты пропускают предварительную компиляцию и связывают затраты в целом. Цена, которую вы платите за более длительное время запуска и (по крайней мере, для Python) более медленную скорость выполнения.

Когда время сборки увеличивается, становится все более важным использовать преимущества систем непрерывной интеграции, таких как Jenkins или TeamCity . Это позволяет отдельным разработчикам (в основном) избегать сложностей сборки с нуля, в то же время проверяя, что изменения не нарушают сборку.

Чарльз Э. Грант
источник
1
Javac не « пропускает предварительную компиляцию и не связывает затраты ». Он пропускает много затрат на оптимизацию, но все же преобразовывает исходный код в байт-код и выполняет много статических проверок в процессе. Он делает столько же ссылок, сколько компилятор Си. Реальное различие в производительности заключается в том, что процесс компиляции Java был разработан в эпоху, когда предполагалось, что можно загрузить всю программу и ее зависимости сразу в память, а не разбивать ее на крошечные куски и повторно обрабатывать одни и те же файлы тысячи раз.
Питер Тейлор
10

Крупные проекты могут занять много времени. Это может быть час или больше для достаточно большого проекта. Есть несколько библиотек, которые я должен скомпилировать из исходного кода на моем компьютере, которые занимают очень много времени - например, opencascade. Само ядро ​​Linux также занимает довольно много времени, если вам нужно собрать его с нуля.

Тем не менее, существуют другие процессы, похожие на компиляцию, которые могут занять гораздо больше времени. Проектирование цифровых схем (для ASIC или FPGA) требует места и маршрута. Шаг «Место и маршрут» - это место, где определяется расположение отдельных логических элементов, триггеров, регистров, ОЗУ и других компонентов вместе с маршрутизацией для межсоединения. Программное обеспечение использует модели синхронизации для определения задержек затвора и маршрутизации для возможных размещений, сравнивает их с ограничениями, предусмотренными ограничениями синхронизации, а затем корректирует места размещения и пути проводов, чтобы попытаться выполнить требования по синхронизации. Иногда программному обеспечению даже придется изменять размеры ворот и добавлять буферы, чтобы соответствовать времени. Этот шаг чрезвычайно сложен в вычислительном отношении и может занять много часов или даже дней. Это также не очень хорошо распараллеливает. Был проект FPGA, над которым я работал год назад или около того, который потреблял около половины FPGA Virtex 6 HXT 565 (~ 300 тыс. Из 565 тыс. LUT) и занимал около 7 часов, чтобы закончить место и маршрут. Я не могу себе представить, сколько времени потребуется для запуска и маршрутизации на чем-то похожем на процессор Core i7 - возможно, по крайней мере, несколько недель.

alex.forencich
источник
4

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

Дополнительным моментом является то, что некоторые проекты должны быть построены для нескольких целевых сред. Когда машины, на которых размещены эти среды, недоступны, сборка должна выполняться путем кросс-компиляции, последовательно на компьютерах, которые у вас есть. Это может привести к значительному времени сборки. Для одного проекта, над которым я работал, ночная сборка заняла бы 10 часов. Горе от того, что ты был тем, кто сломал это!

Я хотел бы добавить, что вам не сойдет с рук такое оправдание, чтобы тратить время. Профессиональный человек должен планировать свои задачи так , что они действительно есть что - то полезное делать в такие периоды.

andy256
источник
3

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

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

Telastyn
источник
2

Это зависит от проекта и среды, в которой он компилируется. Я работал над проектами на C ++, на компиляцию которых ушло несколько минут (в MSVS они были настроены как несколько проектов), что, вероятно, достаточно времени для боя на мечах.

Если вы работаете в большой компании с огромным кодом и базой данных (Proctor and Gamble, Google и т. Д.) Или в небольшой компании или стартапе, ориентированных на один или два основных продукта, которые являются очень сложными (например, научное моделирование и рендеринг), тогда ожидание большого проекта для компиляции - реалистичная вещь, ожидаемая даже на мощных машинах. Это может повлиять на то, как вы разрабатываете и отлаживаете код (а также на то, как часто вы решаете обновлять и объединять изменения посредством контроля версий).

Трикси Вольф
источник