【问题标题】:Recursive static member functions Vs ordinary member functions递归静态成员函数与普通成员函数
【发布时间】:2014-05-03 00:37:22
【问题描述】:

当函数声明为静态成员函数(而不是普通成员函数)时,递归函数是否更快。例如这样的:

class Tree {
  Node* p;
public:
  static int height(Node* n){
     .......
     int lh = height(n->left);
     int rh = height(n->right);
     ......
  }
};

这可能是什么原因?

【问题讨论】:

  • 了解此类事情的最佳方法是先为自己编写一个测试并查看。
  • 您真的必须向我们展示您的替代代码是什么。但它不太可能在现代编译器中产生巨大的影响......
  • 我并不是很关心速度上的差异,但我只是想知道发生这种情况的可能原因。
  • 同时考虑:int height() const { return p->height(); } 并将height 作为Node 的(递归)成员函数。

标签: c++ class recursion static member-functions


【解决方案1】:

在技术意义上这是真的(或者至少它可能是真的*),因为每个非静态成员函数调用都包含一个不可见的this 参数。例如,如果您的示例中的 height 函数是非静态的,则其有效签名将是 int height(Tree* this, Node* n)。所以如果你不需要this,你确实会浪费一些非零循环通过它。

但是,在实践中,这不太重要(当然,具体取决于您在做什么)。因此,编写最有意义的代码,并且只在分析器显示 (a) 您有问题并且 (b) 优化产生影响时才担心进行微优化。

*我说 可能 是真的,因为我怀疑大多数编译器无论如何都会优化掉未使用的参数,但我不能 100% 确定这一点。

【讨论】:

  • 如果内联,它将被优化,但如果不内联,则不会优化(除非编译器能够进行 IPO)。原因很简单:在调用点,编译器不知道函数是否需要this 指针。分析这些类型的最佳方法是简单地查看汇编语言输出。
  • @user3521733 但是......但是现在是星期五晚上......我在和谁开玩笑。我用 VS2013 进行了实验,在抑制内联的发布模式下,它生成了完全相同的汇编代码,有和没有 static。对于调试版本,省略static 会在调用站点产生额外的lea 指令,正如人们所期望的那样。所有代码都在一个 cpp 文件中,这可能是允许优化的原因。
  • 为了好玩,因为我们无事可做,如果你以某种方式发布你的代码,我会用 g++ 和 clang++ 编译它。
  • 实际上,现在我想起来了,对象是否有数据成员并不重要,因为在函数内部它可以引用this。所以我怀疑它正在做一些 IPO。
  • @user3521733 这在评论形式中看起来很可怕,但就是这样:#include <string> #include <iostream> class C { public: int a; /* static */ void f(); }; void C::f() { int c = 0; std::cin >> c; } int main() { C c; c.f(); }
猜你喜欢
  • 1970-01-01
  • 2020-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多