#опытным
Если вы уже дошли до ручки и у вас ежедневный передоз кофеином от безделья во время сборки проекта, пора что-то менять. Но с чего начать? Как понять, что конкретно занимает так много времени при компиляции?
И действительно, семь раз отмерь, один раз отрежь. Сколько бы вы не теоретизировали о проблемных местах в сборке, это не системный подход. Вам нужны цифры, чтобы хоть на что-то объективное опереться. Сегодня поговорим об инструментах анализа сборки.
Здесь будет только gcc и clang, с виндой у нас опыта особо нет. Знающие могут подсказать в комментах. Поехали.
GCC
Есть определенный набор опций компиляции, которые говорят компилятору выводить подробную информацию о внутренних процессах, происходящих при обработке цппшников и хэдэров. Для гцц это:
g++ -fstats -fstack-usage -ftime-report -ftime-report-details -c large_file.cpp -o large_file.o
// или в CMakeLists.txt прописать
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstats -fstack-usage -ftime-report -ftime-report-details")
при компиляции вам выдастся что-то такое:
******
time in header files (total): 0.259532 (22%)
time in main file (total): 0.884263 (76%)
ratio = 0.293501 : 1
******
time in <path_to_header_1>: 0.000444 (0%)
time in <path_to_header_2>: 0.008682 (1%)
time in <path_to_header_3>: 0.885595 (76%)
/.../
Time variable wall GGC
phase setup : 0.05 ( 4%) 1813k ( 3%)
phase parsing : 1.11 ( 94%) 55M ( 97%)
phase lang. deferred : 0.01 ( 1%) 128k ( 0%)
// other metrics
TOTAL : 1.18 57M
Вы получите подробную статистику о времени, потраченном на анализ конкретных хэдэров и на каждый отдельный этап обработки единицы трансляции. Если у вас много шаблонов - вам об этом скажут. Если сложное разрешение перегрузок - тоже. И тд.
И такая портянка генерируется для каждого цппшника. Будьте осторожнее при сборке, используйте make в один поток, иначе не поймете, что куда относится.
Clang
Чтобы получить подобный репорт для шланга нужна опция:
clang++ -ftime-trace -c large_file.cpp -o large_file.o
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftime-trace")
Плюс к этому у шланга с инструментами как всегда по-веселее, чем у гцц. Есть утилитка ClangBuildAnalyzer, который позволяет агрегировать и предоставлять в более читаемом виде информацию о общих таймингах компиляции и самых трудозатратных местах сборки. Можно собрать из исходников по ссылочке и использовать его так:
// обязательно собрать проект с опцией -ftime-trace
ClangBuildAnalyzer --all build/ build_analysis.json
ClangBuildAnalyzer --analyze build_analysis.json
Вывод будет примерно такой:
**** Files that took longest to codegen (compiler backend):
// files list
**** Templates that took longest to instantiate:
// templates list
**** Functions that took longest to compile:
// functions list
etc...
Попробуйте начать с этих инструментов и детально проанализировать, где вы тратите больше всего времени. Если у вас глаза вытекают, глядя на статистику - скормите это добро нейронке. Если слишком много данных для анализа(большой проект), можно скрипт аггрегирующий написать.
В любом случае, измерение - залог качественного результата.
Look before you leap. Stay cool.
#tools