最近看了 effective c++
这本书,书中有一种用模板元编程计算阶乘的骚操作,说是可以将计算从运行时转到编译期间,这样可以提高代码的执行效率。
但我尝试了下,发现并没有比使用 for 循环计算阶乘的方法快,反而花费了更多的时间,代码如下:
#include <chrono>
#include <cstdlib>
#include <iostream>
#include <new>
#include <vector>
using std::size_t;
template <unsigned x>
struct fac {
static const size_t value = x * fac<x - 1>::value;
};
template <>
struct fac<1> {
static const size_t value = 1;
};
// for 循环计算阶乘
size_t fori(size_t v) {
size_t tmp = 1;
for (size_t i = 1; i <= v; i++) {
tmp = tmp * i;
}
return tmp;
}
// 利用模板元编程计算阶乘
constexpr size_t facc() { return fac<901>::value; }
void func() {
// 模板元编程计算耗时
auto start = std::chrono::high_resolution_clock::now();
constexpr auto tmp = facc();
std::cout << tmp << std::endl;
auto end = std::chrono::high_resolution_clock::now();
auto duration =
std::chrono::duration_cast<std::chrono::nanoseconds>(end - start);
std::cout << "Elapsed time: " << duration.count() << " ns"
<< std::endl; // 输出 57466 ns
// for 循环计算耗时
auto start1 = std::chrono::high_resolution_clock::now();
size_t t = fori(901);
std::cout << tmp << std::endl;
auto end1 = std::chrono::high_resolution_clock::now();
auto duration1 =
std::chrono::duration_cast<std::chrono::nanoseconds>(end1 - start1);
std::cout << "Elapsed time: " << duration1.count() << " ns"
<< std::endl; // 输出 1647 ns
}
int main() { func(); }
如果去掉打印,反而是利用模板元编程的更快,确实符合编译期计算提高效率的说法,但这里打印了其结果,反而花费了更多时间。
这是为什么,是编译器自个的优化策略问题还是什么?
编译器版本:gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.