Lou*_*nne 13 c++ templates instantiation boost-mpl template-meta-programming
假设我有以下元函数:
template <typename T>
struct make_pair {
using type = std::pair<
typename std::remove_reference<T>::type,
typename std::remove_reference<T>::type
>;
};
Run Code Online (Sandbox Code Playgroud)
相反,它会提高编译速度(或其他)吗?
template <typename T>
struct make_pair {
using without_reference = typename std::remove_reference<T>::type;
using type = std::pair<without_reference, without_reference>;
};
Run Code Online (Sandbox Code Playgroud)
我看到两种可能性:
编译器每次看到它都必须做一些工作typename std::remove_reference<T>::type.使用中间别名具有某种"缓存"行为,这允许编译器只执行一次工作.
编译时性能是根据编译器必须执行的模板实例化的数量来衡量的.因为std::remove_reference<T>::type引用的类型相同std::remove_reference<T>::type,所以在这两种情况下只需要一个模板实例化,因此两个实现都是等效的WRT编译时性能.
我认为B是对的,但我想确定一下.如果答案结果是编译器特定的,我最感兴趣的是知道Clang和GCC的答案.
编辑:
我对测试程序的编译进行了基准测试,以便使用一些数据.测试程序做了类似的事情:
template <typename ...> struct result;
template <typename T>
struct with_cache {
using without_reference = typename std::remove_reference<T>::type;
using type = result<without_reference, ..., without_reference>;
};
template <typename T>
struct without_cache {
using type = result<
typename std::remove_reference<T>::type,
...,
typename std::remove_reference<T>::type
>;
{ };
using Result = with[out]_cache<int>::type;
Run Code Online (Sandbox Code Playgroud)
这些是10个程序编译的平均时间,其中有10 000个模板参数result<>.
-------------------------
| g++ 4.8 | clang++ 3.2 |
-----------------------------------------
| with cache | 0.1628s | 0.3036s |
-----------------------------------------
| without cache | 0.1573s | 0.3785s |
-----------------------------------------
Run Code Online (Sandbox Code Playgroud)
测试程序由此处提供的脚本生成.
我不能说所有编译器都是如此,但 GCC 以及很可能所有其他主要编译器都会使用记忆化。如果你仔细想想,那几乎是必须的。
考虑下面的代码
&f<X, Y>::some_value == &f<X, Y>::some_value
Run Code Online (Sandbox Code Playgroud)
这必须是正确的,因此编译器必须确保它不会重复方法和静态成员的定义。现在可能还有其他方法可以做到这一点,但这对我来说只是尖叫记忆;我什至没有看到另一种方法来实现这一点(当然,我已经非常努力地考虑过)
当我使用 TMP 时,我希望发生记忆化。如果不这样做,那将是一个真正的痛苦,太慢了。我发现编译时性能存在重大差异的唯一方法是 a) 使用更快的编译器,如 Clang(比 GCC 快 3 倍)并选择不同的算法。根据我的经验,在我看来,小的常数因素在 TMP 中的重要性甚至比在 C 或 C++ 中的重要性还要小。选择正确的算法,尽量不要做不必要的工作,尽量减少实例化的数量,并使用好的编译器(MSVC++ 确实很慢,而且离 C++11 合规性很远,但 GCC 和 Clang 相当不错);这就是你真正能做的。
此外,您应该始终牺牲编译时间来获得更好的代码。过早的编译时优化比普通的过早优化要邪恶得多。如果由于某种原因性能变得严重阻碍开发,则可能存在例外情况;不过我还没有听说过这样的案例。
| 归档时间: |
|
| 查看次数: |
685 次 |
| 最近记录: |