как минимизировать время компиляции языка программирования?

Я собирался написать пост в блоге с подробным описанием простого примера, но он принадлежит вашему SQL.

select case when col = 'reason to display' then
  apex_page.get_url(...)
end as my_col

И определить столбец, чтобы не экранировать специальные символы .

Или посмотрите слайд 58 .

7
задан Mechanical snail 8 September 2012 в 04:02
поделиться

17 ответов

Простой: удостоверьтесь, что компилятор может исходно использовать в своих интересах многоядерные центральные процессоры.

0
ответ дан 6 December 2019 в 07:52
поделиться

В C++ Вы могли использовать распределенную компиляцию с инструментами как Incredibuild

0
ответ дан 6 December 2019 в 07:52
поделиться

Я не видел много работы, сделанной для уменьшения времени компиляции. Но некоторые идеи действительно приходят на ум:

  1. Сохраните грамматику простой. Замысловатая грамматика увеличит Ваше время компиляции.
  2. Попытайтесь использовать параллелизм, или использовать многоядерный GPU или ЦП.
  3. Сравните современного компилятора и посмотрите то, что является узкими местами и что можно сделать в Вас компилятор/язык для предотвращения их.

Если Вы не пишете узкоспециализированный язык, время компиляции не является действительно проблемой..

0
ответ дан 6 December 2019 в 07:52
поделиться
  • Удостоверьтесь, что все может быть скомпилировано время кулака, Вы пытаетесь скомпилировать его. Например, ссылки вперед запрета.
  • Используйте контекстно-свободную грамматику так, чтобы можно было найти корректное дерево синтаксического анализа без таблицы символов.
  • Удостоверьтесь, что семантика может быть выведена из синтаксиса, таким образом, можно создать корректный AST непосредственно, а не путем унавоживания с деревом синтаксического анализа и таблицей символов.
0
ответ дан 6 December 2019 в 07:52
поделиться

Сделайте систему сборки, которая не сосет!

Существует огромная сумма программ там с, возможно, 3 исходными файлами, которые занимают менее чем секунду для компиляции, но прежде чем Вы получите это далеко, необходимо было бы сидеть через автосделать сценарий, который занимает приблизительно 2 минуты, проверяя вещи как размер int. И если Вы идете для компиляции чего-то еще минуту спустя, это заставляет Вас сидеть через почти точно тот же набор тестов.

Таким образом, если Ваш компилятор не делает ужасные вещи пользователю как изменение размера ints или изменяющий реализации основной функции между выполнениями, просто разгрузите ту информацию в файл и позвольте им получить ее за секунду вместо 2 минут.

0
ответ дан 6 December 2019 в 07:52
поделиться

Насколько серьезный компилятор - это?

Если синтаксис не является довольно замысловатым, синтаксический анализатор должен смочь работать не больше, чем в 10-100 раз медленнее, чем просто индексация через входные символы файла.

Точно так же генерация кода должна быть ограничена выходным форматированием.

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

Затем необходимо волноваться о предварительно скомпилированных заголовках, оптимизационных проходах и соединении.

0
ответ дан 6 December 2019 в 07:52
поделиться

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

0
ответ дан 6 December 2019 в 07:52
поделиться

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

Таким образом, если Вы не делаете обширную оптимизацию к исходному коду, ЦП проведет большую часть времени, ожидая данных, которые будут считаны или записаны.

Попробуйте эти правила:

  1. Разработайте свой компилятор для работы в нескольких, независимых шагах. Цель состоит в том, чтобы смочь выполнить каждый шаг в различном потоке, таким образом, можно использовать многоядерные центральные процессоры. Это также поможет параллелизировать целый процесс компиляции (т.е. скомпилировать больше чем один файл одновременно)

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

  2. Попытайтесь позволить компилировать файлы независимо. Например, создайте "пул отсутствующего символа" для проекта. Отсутствующие символы не должны вызывать отказы компиляции как таковые. Если Вы находите отсутствующий символ где-нибудь, удаляете его из пула. Когда все файлы были скомпилированы, проверьте, что пул пуст.

  3. Создайте кэш с важной информацией. Например: Файл X использует символы из файла Y. Таким образом, можно пропустить файл Z компиляции (который ни на что не ссылается в Y), когда Y изменяется. Если Вы хотите пойти один шаг вперед, поместить все символы, которые определяются где угодно в пуле. Если файл изменится таким способом, которым добавляются/удаляются символы, то Вы будете сразу знать, какие файлы затронуты (даже не открывая их).

  4. Скомпилируйте в фоновом режиме. Запустите процесс компилятора, который проверяет каталог проекта на изменения, и скомпилируйте их, как только пользователь сохранил файл. Таким образом, необходимо будет только скомпилировать несколько файлов каждый раз вместо всего. В конечном счете Вы скомпилируете намного больше, но для пользователя, времена оборота будут намного короче (=, пользователь времени должен ожидать, пока она не может выполнить скомпилированный результат после изменения).

  5. Используйте "Как раз вовремя" компилятор (т.е. скомпилируйте файл, когда он будет использоваться, например, в операторе импорта). Проекты затем распределяются в исходной форме и компилируются, когда выполнено впервые. Python делает это. Чтобы заставить это работать, можно предварительно скомпилировать библиотеку во время установки компилятора.

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

9
ответ дан 6 December 2019 в 07:52
поделиться

это зависит, на каком языке/платформе Вы программируете для. для разработки.NET минимизируйте количество проектов, которые Вы имеете в своем решении.

0
ответ дан 6 December 2019 в 07:52
поделиться

У Eiffel была идея различных состояний замороженных, и перекомпиляция не обязательно означала, что целый класс был перекомпилирован.

Насколько можно разбить компилируемые модули, и сколько Вы хотите отслеживать их?

1
ответ дан 6 December 2019 в 07:52
поделиться

Вот выстрел..

Используйте инкрементную компиляцию, если Ваш набор инструментальных средств поддерживает ее. (сделайте, Visual Studio, и т.д.).

Например, в GCC/make, если у Вас есть много файлов для компиляции, но только вносить изменения в одном файле, затем только, что один файл компилируется.

1
ответ дан 6 December 2019 в 07:52
поделиться
  • Сделайте грамматику простой и однозначной, и поэтому быстрой и легкой проанализировать.
  • Установите сильные ограничения для включения файла.
  • Позвольте компиляцию без полной информации каждый раз, когда возможный (например, предварительное объявление в C и C++).
  • Компиляция с одной передачей, если это возможно.
1
ответ дан 6 December 2019 в 07:52
поделиться

Вот некоторые приемы производительности, которые мы изучили путем измерения скорости компиляции и что влияет на нее:

  • Запишите компилятор с двумя передачами: символы к IR, IR для кодирования. (Легче записать компилятор с тремя передачами, который идет символы-> AST-> IR-> код, но это не столь быстро.)

  • Как заключение, не имейте оптимизатора; трудно записать быстрый оптимизатор.

  • Рассмотрите генерирующийся байт-код вместо собственного машинного кода. Виртуальная машина для Lua является хорошей моделью.

  • Попробуйте средство выделения линейного сканирующего регистра или простое средство выделения регистра, которое Fraser и Hanson использовали в lcc.

  • В простом компиляторе лексический анализ часто является самым большим узким местом производительности. Если Вы пишете C или код C++, используйте re2c. При использовании другого языка (который Вы найдете намного более приятным), считайте бумагу aboug re2c и примените извлеченные уроки.

  • Сгенерируйте код, использующий максимальный, жуют, или возможно iburg.

  • Удивительно, ассемблер GNU является узким местом во многих компиляторах. Если можно генерировать двоичный файл непосредственно, сделайте так. Или проверьте Инструментарий Машинного кода Нью-Джерси.

  • Как отмечено выше, разработайте свой язык для предотвращения чего-либо как #include. Или не используйте интерфейсные файлы или предварительно скомпилируйте Ваши интерфейсные файлы. Эта тактика существенно уменьшает burdern на лексическом анализаторе, который, поскольку я сказал, часто самое большое узкое место.

2
ответ дан 6 December 2019 в 07:52
поделиться

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

Оказывается, что самой важной вещью, которую можно оптимизировать, не является грамматика. Это не Ваш лексический анализатор или Ваш синтаксический анализатор также. Вместо этого самой важной вещью с точки зрения скорости является код, который читает в Ваших исходных файлах из диска. Ввод-вывод к диску является медленным. Действительно медленный. Можно в значительной степени измерить скорость компилятора количеством диска I/Os, который это выполняет.

Таким образом, оказывается, что абсолютная лучшая вещь, которую можно сделать для ускорения компилятора, состоит в том, чтобы считать весь файл в память в одном большом вводе-выводе, сделать весь lexing, парсинг, и т.д. от RAM, и затем выписать результат к диску в одном большом вводе-выводе.

Я говорил с одним из главных парней, поддерживающих Комара (компилятор Ada GCC) об этом, и он сказал мне, что на самом деле раньше помещал все, что он мог на псевдодиски так, чтобы даже его файловый ввод-вывод был действительно просто чтениями RAM и записями.

3
ответ дан 6 December 2019 в 07:52
поделиться

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

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

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

Java (источник к байт-коду) страдает, потому что грамматика не дифференцирует объекты и классы - необходимо загрузить класс Foo, чтобы видеть если Foo. Панель. Baz является полем Baz объекта, на который ссылается Панель статическое поле класса Foo или статическое поле Foo. Класс панели. Можно внести изменение в источнике класса Foo между этими двумя, и не изменить источник клиентского кода, но все еще иметь для перекомпиляции клиентского кода, поскольку байт-код дифференцируется между двумя формами даже при том, что синтаксис не делает. AFAIK, которые байт-код Python не дифференцирует между двумя - модули, являются истинными членами своих родителей.

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

C страдает, если Вы используете препроцессор много, но фактическая компиляция быстра; большая часть C кодирует использование typedef struct _X* X_ptr скрыть реализацию лучше, чем C++ делает - заголовок C может легко состоять из определений типов и объявлений функции, давая лучшую инкапсуляцию.

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

2
ответ дан 6 December 2019 в 07:52
поделиться

Одна вещь, удивительно недостающая в ответах до сих пор: сделайте Вас, Вы делаете контекстно-свободную грамматику и т.д. Имейте хороший твердый взгляд на языки, разработанные Wirth, такие как Pascal & Modula-2. Вы не должны повторно реализовывать Паскаля, но дизайн грамматики изготовлен на заказ для быстрой компиляции. Затем посмотрите, можно ли найти какие-либо старые статьи о приемах Anders вытянутый, реализовав Turbo Pascal. Подсказка: табличный.

1
ответ дан 6 December 2019 в 07:52
поделиться

что такое способы, которыми я мог минимизировать его время компиляции?

  • Никакая компиляция (интерпретируемый язык)
  • Отложенный (как раз вовремя) компиляция
  • Инкрементная компиляция
  • Предварительно скомпилированные заголовочные файлы
3
ответ дан 6 December 2019 в 07:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: