【发布时间】:2011-06-19 19:22:53
【问题描述】:
在您对重复的标题感到畏缩之前,另一个问题不适合我在这里提出的问题 (IMO)。所以。
我真的很想在我的应用程序中使用虚函数来让事情变得简单一百倍(这不就是 OOP 的全部内容吗;))。但是我在某处读到它们是以性能为代价的,只看到过早优化的旧人为炒作,我决定在一个小型基准测试中快速旋转它,使用:
CProfiler.cpp
#include "CProfiler.h"
CProfiler::CProfiler(void (*func)(void), unsigned int iterations) {
gettimeofday(&a, 0);
for (;iterations > 0; iterations --) {
func();
}
gettimeofday(&b, 0);
result = (b.tv_sec * (unsigned int)1e6 + b.tv_usec) - (a.tv_sec * (unsigned int)1e6 + a.tv_usec);
};
main.cpp
#include "CProfiler.h"
#include <iostream>
class CC {
protected:
int width, height, area;
};
class VCC {
protected:
int width, height, area;
public:
virtual void set_area () {}
};
class CS: public CC {
public:
void set_area () { area = width * height; }
};
class VCS: public VCC {
public:
void set_area () { area = width * height; }
};
void profileNonVirtual() {
CS *abc = new CS;
abc->set_area();
delete abc;
}
void profileVirtual() {
VCS *abc = new VCS;
abc->set_area();
delete abc;
}
int main() {
int iterations = 5000;
CProfiler prf2(&profileNonVirtual, iterations);
CProfiler prf(&profileVirtual, iterations);
std::cout << prf.result;
std::cout << "\n";
std::cout << prf2.result;
return 0;
}
一开始我只进行了 100 和 10000 次迭代,结果令人担忧:非虚拟化 4 毫秒,虚拟化 250 毫秒!我几乎进入了“nooooooo”,但后来我将迭代次数提高到了大约 500,000 次;看到结果变得几乎完全相同(在没有启用优化标志的情况下可能会慢 5%)。
我的问题是,为什么与大量迭代相比,少量迭代会有如此显着的变化?纯粹是因为虚拟函数在这么多次迭代时在缓存中很热吗?
免责声明
我知道我的“分析”代码并不完美,但它提供了对事物的估计,这在这个级别上是最重要的。此外,我问这些问题是为了学习,而不是仅仅为了优化我的应用程序。
【问题讨论】:
-
"(在不启用优化标志的情况下可能会慢 5%)"——这意味着您正在分析调试/非优化构建。这样做会产生一个通常远没有缺陷的基准。是这样吗?
-
它在 Ubuntu 10.10 上出现故障,使用 g++,和 没有优化标志。
-
您肯定在编译时启用了优化以进行基准测试,对吧?
-
@Daniel 你应该删除新/删除;在分析循环之外预分配对象,进行真正的虚拟调用(即 ptr2base->set_area()),然后运行足够的测试迭代(至少几秒钟),然后使用适当的 cmets 将新结果添加到您的问题中:)跨度>
标签: c++ performance inheritance virtual