【发布时间】:2011-02-24 21:23:01
【问题描述】:
在学校,我们讨论了 C++ 中的virtual 函数,以及它们是如何解析(或找到,或匹配,我不知道'不知道术语是什么——我们不是用英语学习)在执行时而不是编译时。老师还告诉我们,编译时解析比执行时快得多(这样做是有道理的)。然而,一个快速的实验会提出不同的建议。我已经构建了这个小程序:
#include <iostream>
#include <limits.h>
using namespace std;
class A {
public:
void f() {
// do nothing
}
};
class B: public A {
public:
void f() {
// do nothing
}
};
int main() {
unsigned int i;
A *a = new B;
for (i=0; i < UINT_MAX; i++) a->f();
return 0;
}
我编译了上面的程序并将其命名为normal。然后,我将A 修改为如下所示:
class A {
public:
virtual void f() {
// do nothing
}
};
编译并命名为virtual。这是我的结果:
[felix@the-machine C]$ time ./normal
real 0m25.834s
user 0m25.742s
sys 0m0.000s
[felix@the-machine C]$ time ./virtual
real 0m24.630s
user 0m24.472s
sys 0m0.003s
[felix@the-machine C]$ time ./normal
real 0m25.860s
user 0m25.735s
sys 0m0.007s
[felix@the-machine C]$ time ./virtual
real 0m24.514s
user 0m24.475s
sys 0m0.000s
[felix@the-machine C]$ time ./normal
real 0m26.022s
user 0m25.795s
sys 0m0.013s
[felix@the-machine C]$ time ./virtual
real 0m24.503s
user 0m24.468s
sys 0m0.000s
虚拟版本似乎有大约 1 秒的稳定差异。这是为什么呢?
相关与否:双核奔腾 @ 2.80Ghz,两次测试之间没有运行额外的应用程序。 Archlinux 与 gcc 4.5.0。正常编译,如:
$ g++ test.cpp -o normal
另外,-Wall 也不会发出任何警告。
编辑:我已将我的程序分成A.cpp、B.cpp 和main.cpp。另外,我创建了f()(A::f() 和B::f())函数实际上做一些事情(x = 0 - x 其中x 是publicintA 的成员, 在A::A() 中初始化为 1)。编译成六个版本,这是我的最终结果:
[felix@the-machine poo]$ time ./normal-unoptimized
real 0m31.172s
user 0m30.621s
sys 0m0.033s
[felix@the-machine poo]$ time ./normal-O2
real 0m2.417s
user 0m2.363s
sys 0m0.007s
[felix@the-machine poo]$ time ./normal-O3
real 0m2.495s
user 0m2.447s
sys 0m0.000s
[felix@the-machine poo]$ time ./virtual-unoptimized
real 0m32.386s
user 0m32.111s
sys 0m0.010s
[felix@the-machine poo]$ time ./virtual-O2
real 0m26.875s
user 0m26.668s
sys 0m0.003s
[felix@the-machine poo]$ time ./virtual-O3
real 0m26.905s
user 0m26.645s
sys 0m0.017s
未优化在虚拟时仍然快 1 秒,我觉得这有点奇怪。但这是一个很好的实验,感谢大家的回答!
【问题讨论】:
-
你能用-O3(3级优化)试试吗?
-
我认为您要查找的术语称为 vtable。
-
啊,又一个微基准测试!可爱的,我开始想念他们了……
-
我可以通过向其中添加代码来加速循环。也从来没有得到一个好的答案。也许有一些关于现代处理器的事情是人类从未想过的? stackoverflow.com/questions/688325/…