以下のコードは、アッカーマン関数を用いてそれぞれの関数の実行速度を調べるものです。
時間を変えて何度か実行した結果が下の画像になります。単位はミリ秒です。
すると、関数オブジェクト(コールバック)が関数よりも速いという結果が出ました。
関数オブジェクトのほうが速いというのであれば、実装する全ての関数を関数オブジェクトとして実装したほうが良いのでしょうか?
また関数の戻り値を型推論にして何度か実行してみたところ、実行時間が若干増えてしまいました。(何度やっても平均時間が型推論でないときを下回ることはなかった)
型推論はコンパイル時で完結するものだと思っているのですが、それは間違いなのでしょうか?それともただ単に実行タイミングが悪かったのでしょうか?
ついでに教えていただけたら幸いです。
Cpp
1#include <iostream> 2#include <chrono> 3using namespace std; 4 5// アッカーマン関数 6int acker(int x, int y) { 7 if (x == 0) return y + 1; 8 if (y == 0) return acker(x - 1, 1); 9 return acker(x - 1, acker(x, y - 1)); 10} 11 12// アッカーマン関数オブジェクト 13struct ackerman { 14 /*int operator()(int x, int y) { 15 if (x == 0) return y + 1; 16 if (y == 0) return ackerman()(x - 1, 1); 17 return ackerman()(x - 1, ackerman()(x, y - 1)); 18 }*/ 19 20 // callback 21 int operator()(ackerman& ack, int x, int y) { 22 if (x == 0) return y + 1; 23 if (y == 0) return ack(ack, x - 1, 1); 24 return ack(ack, x - 1, ack(ack, x, y - 1)); 25 } 26}; 27 28int main() 29{ 30 constexpr int N = 10; 31 constexpr int TIMES = 10; 32 constexpr int TIMES_TIMES = 10; 33 double ave = 0; 34 double aveave = 0; 35 ackerman ack; 36 int a[N]; 37 38 for (int l = 0; l < TIMES_TIMES; l++) { 39 for (int k = 0; k < TIMES; k++) { 40 auto start = chrono::system_clock::now(); 41 42 for (int i = 0; i < N; i++) { 43 //a[i] = acker(3, i); 44 //a[i] = ack(3, i); 45 //a[i] = ack(ack, 3, i); 46 } 47 48 auto end = chrono::system_clock::now(); 49 double time = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count(); 50 51 //cout << time << "[ms]" << endl; 52 ave += time; 53 } 54 cout << "ave=" << (ave / N) << "[ms]" << endl; 55 aveave += ave; 56 ave = 0; 57 } 58 cout << "aveave=" << (aveave / TIMES_TIMES * TIMES) << "[ms]" << endl; 59 60 return 0; 61}
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/09/22 12:20