Почему компиляции занимают так много времени? - PullRequest
15 голосов
/ 26 февраля 2009

Я проектирую язык программирования, и одна из проблем, о которых я думал, заключалась в том, почему языки программирования занимают много времени для компиляции. Предполагается, что c ++ занимает много времени, потому что он должен анализировать и компилировать заголовок каждый раз, когда компилирует файл. Но i -heard- предварительно скомпилированные заголовки занимают столько времени? я подозреваю, что c ++ не единственный язык, который имеет эту проблему.

Ответы [ 7 ]

18 голосов
/ 26 февраля 2009

Одна специфическая проблема C ++, которая делает его ужасно медленным, состоит в том, что, в отличие от почти любого другого языка, вы не можете анализировать его независимо от семантического анализа.

14 голосов
/ 26 февраля 2009

Компиляция - сложный процесс, который включает в себя довольно много шагов:

  • Сканирование / Lexing
  • Синтаксический
  • Промежуточная генерация кода
  • Возможно, оптимизация промежуточного кода
  • Генерация целевого машинного кода
  • Опционально Машинно-зависимая оптимизация кода

(Оставляя в стороне ссылки.)

Естественно, это займет некоторое время для более длинных программ.

8 голосов
/ 26 февраля 2009

Предварительно скомпилированные заголовки способ быстрее, как известно, по крайней мере, с 1988 года.

Обычная причина, по которой компилятор C или C ++ занимает много времени, заключается в том, что он должен #include, preprocess, а затем lex gazillions токенов.

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

gcc -O использует очень эффективную, но несколько медленную технику оптимизации, разработанную Крисом Фрейзером и Джеком Дэвидсоном. Большинство других оптимизаторов могут работать медленно, потому что они требуют многократных итераций для довольно больших структур данных.

6 голосов
/ 26 февраля 2009

Компиляция не требует , чтобы занять много времени: tcc компилирует ANSI c достаточно быстро, чтобы быть полезным в качестве интерпретатора .

О чем подумать:

  1. Сложность при сканировании и разборе пропусков. Предположительно, потребуются долгие ожидания, а также контекстные (в отличие от контекстно-свободных) языки.
  2. Внутреннее представительство. Создание и работа над большим и интересным AST займет некоторое время. Предположительно, вам следует использовать простейшее внутреннее представление, которое будет поддерживать функции, которые вы хотите реализовать.
  3. Оптимизация. Оптимизация суетливая. Вам нужно проверить множество различных условий. Вы, вероятно, хотите сделать несколько проходов. Все это займет время.
6 голосов
/ 26 февраля 2009

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

Упрощенная структура "заголовочного файла" в C ++ способствует снижению производительности, хотя часто могут помочь предварительно скомпилированные заголовки. C ++ является гораздо более сложным языком, чем C, и поэтому компиляторы C обычно быстрее.

3 голосов
/ 26 февраля 2009

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

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

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

Некоторые компиляторы (действительно IDE) выполняют инкрементную компиляцию в фоновом режиме, так что они (почти) всегда близки к полностью скомпилированным.

0 голосов
/ 18 февраля 2018

Я думаю, что другие ответы здесь пропустили некоторые важные части ситуации, которые замедляют компиляцию C ++:

  • Модель компиляции, которая сохраняет .obj / .o файлы на диск, читает их обратно, затем связывает их
  • Связывание вообще и плохие медленные линкеры в частности
  • Слишком сложный макропроцессор
  • Произвольно сложная система Тьюринга, полная шаблонная система
  • Вложенное и повторное включение исходных файлов, даже с #pragma once
  • Пользовательская фрагментация, разбивающая код на слишком много файлов (в крайнем случае даже до одной функции на файл)
  • Раздутые или не требующие больших усилий внутренние структуры данных в компиляторе
  • Стандартная библиотека перегружена, злоупотребление шаблоном

Напротив, они не замедляют компиляцию C ++:

  • Сканирование / Lexing
  • Синтаксический
  • Промежуточная генерация кода
  • Генерация целевого машинного кода

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

...