コンパイル時定数を利用するにあたって、テンプレートメタプログラミングの他に、関数の前にconstexprを付けることでinline展開&コンパイル時計算が保証されるということをいくつかのサイトで拝見したことがあります。
そこで実験として、フィナボッチ数列を再帰関数を利用して計算し、その時間を計ってみることにしたのですが、その結果が
-constexpr関数 time[ms]:3713
-テンプレート time[ms]:0
-ノーマル関数 time[ms]:3617 (求める値を40にした場合)
となってしまいました。コンパイル時計算どころか、ノーマル関数より時間が掛かっています・・・
何故こうなったのか、記述が間違っているのか、あるいはそもそもの根本が間違っていたのかお教えください。
C++
1#include <iostream> 2#include <chrono> 3using namespace std; 4 5// フィナボッチ数列(ノーマル) 6unsigned long fina(unsigned long n) { 7 /*if (n <= 2) 8 return 1; 9 return fina(n - 1) + fina(n - 2);*/ 10 11 return (n <= 2) ? 1 : (fina(n - 1) + fina(n - 2)); 12} 13 14// フィナボッチ数列(constexpr) 15constexpr unsigned long finaConst(unsigned long n) { 16 return (n <= 2) ? 1 : (finaConst(n - 1) + finaConst(n - 2)); 17} 18 19// フィナボッチ数列メタプログラミング 20template <unsigned long N> struct Fina { 21 enum { value = Fina<N-1>::value + Fina<N-2>::value }; 22}; 23template <> struct Fina<2> { 24 enum { value = 1 }; 25}; 26template <> struct Fina<1> { 27 enum { value = 1 }; 28}; 29 30// メイン関数 31auto main() ->int { 32 // 関数(constexpr)を利用した場合 33 auto start = chrono::system_clock::now(); 34 cout << finaConst(40) << endl; 35 auto end = chrono::system_clock::now(); 36 cout << "constexpr time[ms]:" << (double)chrono::duration_cast<chrono::milliseconds>(end - start).count() << endl; 37 38 39 // テンプレートを利用した場合 40 auto start2 = chrono::system_clock::now(); 41 cout << Fina<40>::value << endl; 42 auto end2 = chrono::system_clock::now(); 43 cout << "template time[ms]:" << (double)chrono::duration_cast<chrono::milliseconds>(end2 - start2).count() << endl; 44 45 46 // 関数(ノーマル)を利用した場合 47 auto start3 = chrono::system_clock::now(); 48 cout << fina(40) << endl; 49 auto end3 = chrono::system_clock::now(); 50 cout << "nomal time[ms]:" << (double)chrono::duration_cast<chrono::milliseconds>(end3 - start3).count() << endl; 51 52 return 0; 53}
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/01/09 13:22 編集
2019/01/09 13:34
2019/01/09 13:37
2019/01/09 16:08
2019/01/09 16:59