Как правило, использование шаблонов функций значительно удлиняет компиляцию.
Друг предложил мне проверить модули (C++20) на предмет оптимизации.
Не думаю, что это как-то повлияет на скорость компиляции.
Не знаю, как это проверить, поэтому и спрашиваю здесь.
Будет ли следующий код каким-то волшебным образом оптимизировать процесс сборки?
Определение все равно придется создать и скомпилировать, так что это не будет иметь никакого значения?
математика.ixx:
module;
#include <typeinfo>
export module math;
import <iostream>;
export
template<typename T>
T square(T x) {
std::cout << typeid(T).name() << std::endl;
return x * x;
}
main.cpp
import math;
void main() {
square(int());
square(double());
}
вы можете проверить это, измерив время, необходимое для компиляции кода. Я ожидаю, что для того, чтобы какой-либо эффект был значительным, вам нужно сгенерировать некоторый код, в котором определены и реализованы многие шаблоны функций. Прежде всего, вам нужна альтернатива для сравнения.
Будет не быстро, если каждый раз все перекомпилировать. Просто перекомпилируйте именно то, что нужно w.r.t. изменения, которые вы внесли с момента последней компиляции. Вы также можете использовать предварительно скомпилированные заголовки, чтобы сделать эту часть быстрее.
После некоторых экспериментов с модулями C++20 я теперь рассматриваю их как улучшенную альтернативу предварительно скомпилированным заголовкам. Они действительно могут увеличить скорость компиляции, но не так сильно по сравнению с предварительно скомпилированными заголовками. Время синтаксического анализа действительно может быть значительно уменьшено, но не время создания экземпляра шаблона.
@prapin, учитывая то, что я читал в блогах разработчиков компиляторов ... по большей части именно так они реализованы. Так что это почти точно в цель. Они по-прежнему поощряют их использование, потому что это означает меньше проблем при изменении модуля, только модули, импортирующие этот модуль, должны быть перекомпилированы.
Пример кода слишком тривиален, чтобы модули могли иметь какое-либо реальное применение. Один файл, который включает в себя второй файл, и ничего больше не содержит, не является проблемой компиляции. Это все равно, что пытаться измерить скорость сложения двух целочисленных литералов, а затем делать заявление о качестве оператора сложения C++.
С точки зрения производительности модули решают следующую проблему: они не позволяют стоимости перекомпиляции одного файла быть равной стоимости перекомпиляции каждого файла, включаемого первым файлом, независимо от того, изменились ли включаемые файлы.
Если вы #include <vector>
работаете с простой программой, ваш исходный файл теперь содержит тысячи строк кода. Если вы измените этот исходный файл, компилятору придется перекомпилировать тысячи строк кода, которые не изменились. Если у вас есть 1000 файлов, каждый из которых включает <vector>
, у вас теперь есть 1000 идентичных копий <vector>
, которые компилятор должен компилировать каждый раз, когда вы компилируете все эти файлы.
Это то, что модули предотвращают. Если вы импортируете модуль для библиотеки, изменение исходного файла не потребует перекомпиляции включенных заголовков. Если вы импортируете десятки модулей в сотни или тысячи файлов, это довольно быстро складывается.
Предмодули, внесение небольшого изменения в широко включенный заголовок вызывает полную перекомпиляцию всего вашего проекта. В полностью модульной кодовой базе будет много файлов, которые будут перекомпилированы. Но чего не происходит, так это того, что вы перекомпилируете материал, который не зависел от изменений. Возможно, вы изменили широко используемый заголовок, но не изменили стандартную библиотеку C++. Так что, если вы включили его через модули, то <vector>
и тому подобное не будут перекомпилированы.
Именно здесь модули сохраняют производительность.
"В общем ..." ? Правда?