如何统计C++递归函数各代码段的累计总执行时间
递归场景下累计统计函数总执行时间实现方案
问题核心
当前代码的计时逻辑写在递归函数内部,每次进入递归层级都会独立计算单次调用耗时并直接打印,没有跨递归层级的累加逻辑,因此只能得到单轮调用的时长,无法得到全递归链路的累计总耗时。递归深度运行时才可知的场景下,使用静态变量做跨层累加是可行方向,之前static方案失效通常是未处理好递归入口标记、变量被意外重置、未做累加直接覆盖值导致的。
修正后完整代码
#include <iostream> #include <unistd.h> #include <chrono> using namespace std; using namespace std::chrono; int recursive(int); void foo(); void bar(); int main() { int n = 5; // 该值仅在运行时可知 int result = recursive(n); // 如需多次调用recursive,重复调用即可,计时逻辑会自动重置累计值 // int result2 = recursive(10); return 0; } int recursive(int n) { // 静态变量全局仅初始化一次,所有递归层级共享同一份数据 static microseconds total_recursive_cost{0}; static seconds total_foo_cost{0}; static seconds total_bar_cost{0}; static bool is_outer_entry = true; // 标记是否为最外层递归入口 // 最外层入口触发时,重置所有累计值,避免上次调用的结果干扰 bool current_level_is_outer = is_outer_entry; if (current_level_is_outer) { total_recursive_cost = microseconds::zero(); total_foo_cost = seconds::zero(); total_bar_cost = seconds::zero(); is_outer_entry = false; } // 统计递归核心逻辑耗时 auto start = high_resolution_clock::now(); if (n > 1) { recursive(n - 1); n = n - 1; } auto stop = high_resolution_clock::now(); total_recursive_cost += duration_cast<microseconds>(stop - start); // 此处为不需要计时的其他函数调用与计算逻辑 // 累计foo耗时 start = high_resolution_clock::now(); foo(); stop = high_resolution_clock::now(); total_foo_cost += duration_cast<seconds>(stop - start); // 此处为不需要计时的其他函数调用与计算逻辑 // 累计bar耗时 start = high_resolution_clock::now(); bar(); stop = high_resolution_clock::now(); total_bar_cost += duration_cast<seconds>(stop - start); // 所有内层递归执行完成,回到最外层时统一打印总耗时 if (current_level_is_outer) { is_outer_entry = true; cout << "递归逻辑总执行时间: " << total_recursive_cost.count() << " 微秒" << endl; cout << "foo()累计总执行时间: " << total_foo_cost.count() << " 秒" << endl; cout << "bar()累计总执行时间: " << total_bar_cost.count() << " 秒" << endl; } return n; } void foo() { // 复杂函数 sleep(1); } void bar() { // 另一复杂函数 sleep(2); }
关键逻辑说明
- 静态变量特性:用
static修饰的累计变量只会在程序首次运行到声明位置时初始化一次,后续所有递归调用都会访问同一个变量,天然适合跨递归层级做数值累加。 - 入口标记作用:
is_outer_entry标记用来区分当前是最外层第一次调用,还是内层递归调用:最外层进入时清空历史累计值,避免多次调用recursive时计数累加错误;所有递归执行完成回到最外层时,才统一打印最终总耗时,避免内层递归重复输出单次结果。 - 运行验证:传入n=5时,foo会被调用5次,累计总耗时输出5秒;bar会被调用5次,累计总耗时输出10秒,符合预期。
- 多线程适配:如果需要在多线程环境下使用,把静态变量前加
thread_local修饰,改成线程局部存储即可,避免多线程同时修改同一个静态变量导致计数错误。
注意:不要把累计变量的声明放在递归入口判断逻辑内部,否则会导致每次进入递归都重新初始化变量,无法实现累加效果。
内容的提问来源于stack exchange,提问作者Fornax-A
相关产品推荐
相关产品推荐

