Оптимизировать время компиляции шаблонов в С++/gcc
В большом проекте у нас много классов (тысяч), и для каждого из них специальный тип интеллектуального указателя определяется с помощью typedef. Этот тип интеллектуального указателя является классом шаблона. Когда я компилирую с помощью "gcc -Q", я вижу, что потрачено много времени на сбор этих умных указателей для каждого класса. То есть я вижу прокрутку smartptr<class1>::methods, then smartptr<class2>::methods... smartptr<class2000>::methods
на экране, поскольку gcc обрабатывает их.
Есть ли уловка, чтобы ускорить этот процесс? Эти классы одинаковы с точки зрения smartptr, без тэков enable_if и т.д.
Что я сейчас пытаюсь сделать:
- возможно, создать базовый класс без шаблонов с несколькими распространенными методами.
- использовать класс extern template для сокращения символов ссылок (и время создания экземпляра? еще не уверен)
Но все вышеперечисленное не является полным решением. Интересно, есть ли другой способ оптимизировать время компиляции, трюк, чтобы gcc знал, что, например, если он анализировал smartptr, как только он мог применять одно и то же знание снова и снова при просмотре других специализаций, потому что код генерации один и тот же.
Да, я знаю, что это совсем не то же самое... Но это просто сумасшедшая идея.
Или, может быть, есть другие трюки, о которых я не знаю, что может ускорить компиляцию. (Чтобы дать представление о том, что я говорю, мы могли бы оптимизировать другой шаблон, исключив его статический экземпляр элементов данных, что значительно сократило время компиляции. Это не было очевидно вообще.)
Ответы
Ответ 1
Не определенно GCC, но я думаю, что идея получения smartptr
из базового класса без шаблонов звучит как хорошая ставка. Умный указатель является хорошим кандидатом для такого подхода, потому что большая часть кода, который многократно генерируется, не заботится о том, чтобы указатель не был void*
. (Я бы сместил столько кода, насколько это возможно, чтобы шаблон шаблона делал немного больше, чем прикладывать к void*
и void*
там, где это необходимо.)
Кроме того, если у вас есть тысячи классов, которые в значительной степени полагаются на smartptr
, то сначала следует рассмотреть проблему в зародыше. Только тогда, когда это произойдет, я перейду к клиентскому коду smartptr
(в этот момент методы, позволяющие обойти общий заголовок, заслуживают рассмотрения).
Что касается выражений шаблонов extern, у меня нет опыта, но похоже, что вам нужно добавить объявление extern
для каждого typedef
. Примечательно, что противоположный эффект форсирования полного экземпляра выполняется следующим образом:
template class smartptr<MyClass>;
Я бы дважды проверял, что эта строка не сопровождает ни один из ваших typedef
s!
Ответ 2
Предварительно скомпилированный заголовок
Если ваши изменения кода не находятся в заголовке, это может реально помочь сократить время компиляции.
(src)