Я использую библиотеку glm
, которая представляет собой набор математических утилит, предназначенных только для заголовков, предназначенных для трехмерной графики. Используя -ftime-trace
в Clang и ClangBuildAnalyzer
, я заметил, что много времени тратится на создание экземпляров glm
типов:
**** Templates that took longest to instantiate:
16872 ms: glm::vec<4, signed char, glm::packed_highp> (78 times, avg 216 ms)
15675 ms: glm::vec<4, unsigned char, glm::packed_highp> (78 times, avg 200 ms)
15578 ms: glm::vec<4, float, glm::packed_highp> (78 times, avg 199 ms)
...
Итак, Я решил создать заголовок / исходную пару оболочки для glm
и использовать extern template
, чтобы избежать ненужных реализаций:
// glmwrapper.h
#pragma once
#include <glm.hpp>
extern template struct glm::vec<4, signed char, glm::packed_highp>;
extern template struct glm::vec<4, unsigned char, glm::packed_highp>;
extern template struct glm::vec<4, float, glm::packed_highp>;
// glmwrapper.cpp
template struct glm::vec<4, signed char, glm::packed_highp>;
template struct glm::vec<4, unsigned char, glm::packed_highp>;
template struct glm::vec<4, float, glm::packed_highp>;
Теперь в моем проекте вместо включения <glm.hpp>
, Я включаю "glmwrapper.h"
вместо этого. К сожалению, это ничего не изменило. Использование -ftime-trace
и ClangBuildAnalyzer
снова сообщает о том же количестве экземпляров. Также нет измеримой разницы во времени компиляции.
I подозревают , что это потому, что #include <glm.hpp>
действительно заканчивается включением определения шаблона, и в этот момент последующие объявления extern template
просто избыточно.
Есть ли способ достичь того, что я хочу, без изменения библиотеки glm
?
В псевдокоде я хочу что-то вроде этого:
// glmwrapper.h (psuedocode)
#pragma once
#include <glm.hpp>
// Make definition of the templates unavailable:
undefine template struct glm::vec<4, signed char, glm::packed_highp>;
undefine template struct glm::vec<4, unsigned char, glm::packed_highp>;
undefine template struct glm::vec<4, float, glm::packed_highp>;
// Make declaration of the templates available:
extern template struct glm::vec<4, signed char, glm::packed_highp>;
extern template struct glm::vec<4, unsigned char, glm::packed_highp>;
extern template struct glm::vec<4, float, glm::packed_highp>;
// glmwrapper.cpp (psuedocode)
// Define templates only in the `.cpp`, not in the header:
template struct glm::vec<4, signed char, glm::packed_highp>;
template struct glm::vec<4, unsigned char, glm::packed_highp>;
template struct glm::vec<4, float, glm::packed_highp>;