为什么大小..(T)这么慢?在没有大小的情况下实现C++14 make_index_sequence.(T)
why sizeof...(T) so slow? implement C++14 make_index_sequence without sizeof...(T)
我发现C++14的实现make_index_sequence"算法":
template< int ... > struct index_sequence{ using type = index_sequence; };
template< typename T> using invoke = typename T :: type ;
template< typename T, typename U > struct concate;
template< int ...i, int ... j>
struct concate< index_sequence<i...>, index_sequence<j...> >
: index_sequence< i... , (j + sizeof ... (i ) )... > {};
// /
// ----------
// I think here is slowly.
template< int n>
struct make_index_sequence_help : concate<
invoke< make_index_sequence_help<n/2>>,
invoke< make_index_sequence_help<n-n/2>>
> {};
template<> struct make_index_sequence_help <0> : index_sequence<>{};
template<> struct make_index_sequence_help <1> : index_sequence<0>{};
template< int n> using make_index_sequence = invoke< make_index_sequence_help<n> >;
int main()
{
using iseq = make_index_sequence< 1024 > ; // successfull
using jseq = make_index_sequence< 1024 * 16 > ; // a lot of compile time!!!
using kseq = make_index_sequence< 1024 * 64 > ; // can't compile: memory exhauted!!!
};
但是,当我更换尺寸时...(i) 从"concate"到具体数字,然后make_index_sequence<1024 *64> - 编译速度非常快。
template< int s, typename T, typename U > struct concate;
template< int s, int ...i, int ...j >
struct concate< s, index_sequence<i...>, index_sequence<j...> >
: index_sequence< i..., ( j + s ) ... > {};
// and
template< int n >
struct make_index_sequence_help : concate<
n / 2 ,
invoke< make_index_sequence_help< n / 2 > >,
invoke< make_index_sequence_help< n - n/2 > >
>{};
问:为什么尺寸...(一)这么慢?
我用 gcc 4.8.1 进行测试更新:
对于第一种情况:(仅限 1024 和 1024*16)。
g++ -Wall -c "ctx_fptr.cpp" -g -O2 -std=c++11 -ftime-report
Execution times (seconds)
garbage collection : 0.06 ( 1%) usr 0.00 ( 0%) sys 0.06 ( 0%) wall 0 kB ( 0%) ggc
preprocessing : 0.03 ( 0%) usr 0.04 ( 2%) sys 0.09 ( 1%) wall 293 kB ( 0%) ggc
parser : 10.41 (97%) usr 1.61 (95%) sys 12.01 (96%) wall 2829842 kB (99%) ggc
name lookup : 0.12 ( 1%) usr 0.04 ( 2%) sys 0.23 ( 2%) wall 7236 kB ( 0%) ggc
dead store elim1 : 0.01 ( 0%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc
symout : 0.15 ( 1%) usr 0.00 ( 0%) sys 0.15 ( 1%) wall 12891 kB ( 0%) ggc
unaccounted todo : 0.00 ( 0%) usr 0.01 ( 1%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc
TOTAL : 10.78 1.70 12.55 2850835 kB
对于第二种情况:(所有 1024、1024*16 和 1024*64 )
g++ -Wall -c "ctx_fptr.cpp" -g -O2 -std=c++11 -ftime-report
Execution times (seconds)
preprocessing : 0.02 ( 2%) usr 0.01 ( 5%) sys 0.05 ( 4%) wall 293 kB ( 0%) ggc
parser : 0.54 (45%) usr 0.10 (53%) sys 0.71 (50%) wall 95339 kB (58%) ggc
name lookup : 0.47 (39%) usr 0.04 (21%) sys 0.47 (33%) wall 20197 kB (12%) ggc
tree PRE : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 1 kB ( 0%) ggc
varconst : 0.00 ( 0%) usr 0.01 ( 5%) sys 0.00 ( 0%) wall 17 kB ( 0%) ggc
symout : 0.17 (14%) usr 0.03 (16%) sys 0.18 (13%) wall 47092 kB (29%) ggc
TOTAL : 1.21 0.19 1.41 163493 kB
编译速度很慢,并且会占用大量内存,因为您正在递归扩展模板。这是在编译时完成的,它创建大量类型,这会使用大量内存。它不是由大小或任何其他单个语句引起的。正是递归导致模板扩展的每一点都变得昂贵。
我在 VC++ 中遇到了完全相同的问题——我发现当我将更大的常量传递给我编写的模板函数时,我的编译会变得任意慢。
当然,就我而言,我试图让编译器运行缓慢。但是,也许这会有所帮助:
https://randomascii.wordpress.com/2014/03/10/making-compiles-slow/
相关文章:
- 在没有未定义行为的情况下实现类似std::vector的容器
- C++标准是否允许<double>在没有开销的情况下实现 std::可选
- 我可以在没有堆栈的情况下在二叉搜索树中实现迭代器吗?
- 如何在编译器C++不智能的情况下实现 GLSL vec* 构造语法?
- 为什么在这种情况下不调用我的虚拟函数实现?
- 我们可以在不使用head指针的情况下通过使用head的简单变量而不是head的指针来实现链表吗
- 在确定有实现的情况下获取HTTP 501未实现
- 在不创建新节点的情况下实现带有映射的trie
- 在这种情况下,有什么正确的方法可以实现锁定吗?
- 如何在不停滞主循环的情况下实现对话系统?
- 如何在不引入未来对象切片的情况下实现 ICloneable
- 是否可以在不依赖内置编译器的情况下拥有is_trivially_constructible的库实现
- 如何在没有参数的情况下实现返回双向链表大小的函数?int size() const.
- 有没有办法在不重新实现的情况下从子类中标记父级的虚拟函数 final。
- 如何在不使用函数或类的情况下重复代码段,以便在C++中实现高性能循环
- 在C++中,我不能在不分离标头和 cpp 的情况下实现此类吗?
- 在没有限定的情况下从 T 构造函数调用类 T 的纯虚拟实现?
- 如何在不修改C 中的LHS参数的情况下实现` `运算符
- 如何在不使用 lambda 表达式的情况下实现特定的比较器
- 如何在不必绑定到特定类的情况下实现观察者模式