我发现C++ 14 make_index_sequence的实行 '算法':当我更换的sizeof为什么sizeof ...(T)这么慢?实现C++ 14 make_index_sequence没有...的sizeof(T)
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!!!
};
但是,...(我)从'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 > >
>{};
问:为什么sizeof ...(i)这么慢?
对于第一种情况:(仅1024和1024 * 16)
我用gcc 4.8.1 更新测试。
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
模板扩张和处理“解释”的GCC编译器内缓慢的*编译时间*(而不是在编译的代码的运行时)。编译器需要生成大的AST(具有大量的元数据,例如精确的源位置) –
Q.您的证据在哪里?是什么让你认为它是所有东西的大小?这只是编译时的符号表查找。 – EJP
您可以使用在线编译器进行测试。 http://ideone.com/TLuDiA。我问关于编译时间,而不是运行时。 –