跳转至

无法内联的函数调用优化

(1)递归(Recursion):栈开销与缓存失效

  • 问题本质:递归通过函数调用栈实现,每次调用需保存参数、局部变量、寄存器状态,栈开销大;且递归深度过深易引发栈溢出,同时破坏数据局部性,导致缓存命中率下降;
  • 优化方案:

  • 递归转迭代:将递归算法改写为循环,用显式栈(如数组模拟栈)存储中间状态。

// 递归版本(低效)
void preorder_recursive(Node* root) {
  if (root) {
    visit(root);
    preorder_recursive(root->left);
    preorder_recursive(root->right);
  }
}

// 迭代版本(高效)
void preorder_iterative(Node* root) {
  std::stack<Node*> s;
  while (root || !s.empty()) {
    if (root) {
      visit(root);
      s.push(root->right);
      root = root->left;
    } else {
      root = s.top();
      s.pop();
    }
  }
}
2. **尾递归消除**:对尾递归(递归调用为函数最后一步),改写为循环,避免栈开销累积。
void preorder_tail_rec(Node* root) {
  while (root) {
    visit(root);
    preorder_tail_rec(root->left);
    root = root->right;  // 尾递归改为循环变量更新
  }
}

(2)函数参数传递:值传递vs引用传递

  • 问题本质:传递大对象(如std::vector、自定义矩阵类)时,值传递会触发对象拷贝(调用拷贝构造函数),开销远高于引用传递;
  • 优化方案:

  • 大对象用 const& 传递:对无需修改的参数,用“const 类型&”传递,避免拷贝,例如void process(const Matrix& mat);

  • 小类型直接值传递:对int、float等标量类型,值传递开销与引用传递相当(甚至更快,避免指针间接访问),无需强行用引用;
  • 避免临时对象传递:向引用参数传递常量(如process(5))时,编译器会自动创建临时对象,若需频繁传递常量,可重载函数适配常量参数(如void process(int val))。