C++ 创建对象内部/外部循环:分配和速度
我通过在一个循环中调用成员函数C++ 创建对象内部/外部循环:分配和速度,c++,performance,class,C++,Performance,Class,我通过在一个循环中调用成员函数quarture1M次并对整个循环计时(如果您知道更好的方法,请让我知道!),对我的GaussQuadrature模板类的一部分进行基准测试。在这个类的预期应用程序中,构造函数将被调用一次,例程将被调用多次,但我尝试在循环内部调用构造函数1M次,在循环外部调用构造函数1M次,只是为了看看哪个更快 如果我在循环中调用构造函数,那么每次迭代都会调用该构造函数,但看起来它被分配到了相同的内存空间(注意,对于下面的代码段,首先有一条语句std::cout,在进行计时测试时,
quarture
1M次并对整个循环计时(如果您知道更好的方法,请让我知道!),对我的GaussQuadrature
模板类的一部分进行基准测试。在这个类的预期应用程序中,构造函数将被调用一次,例程将被调用多次,但我尝试在循环内部调用构造函数1M次,在循环外部调用构造函数1M次,只是为了看看哪个更快
std::cout,在进行计时测试时,您需要关闭任何文本输出,例如printfs和couts。这一点很重要,因为通过包含它们,您隐藏了类的真实性能。您的测试方法还可以。调用算法100万次是合理的。但是记住缓存。根据内存管理器的行为,可以接收相同的内存指针。最后,我想,在注释掉文本输出后,第二个实现将比第一个更快
最后建议:您可能更喜欢使用QueryPerformanceFrequency和
QueryPerformanceCounter函数用于更精确的计时。这可能是编译器所做优化的结果。for循环可以自动“展开”,最大限度地减少分支,而且这种展开还可以通过CPU的内部并行性和流水线来使用
如果循环中的语句彼此独立(即循环中较早出现的语句不影响其后的语句),则这些语句可能会并行执行
尝试禁用所有优化并再次检查。他得到的是相同的指针,因为它是在堆栈上分配的。每次通过循环,它都被分配和释放,并且堆栈上每次都有相同的插槽可用。是的,我同意你的看法,我不想让他更加困惑:)@SemihOzmen我实际上是在没有print语句的情况下计时的;请参阅我更新的帖子。有没有想过为什么调用1M次会比只调用一次更快?正如我之前所说,内存缓存会导致这种行为。为了获得更多关于编译器优化和CPU硬件设置的详细信息,请阅读正如我之前建议的那样,尝试使用更精确的计时函数。现在的编译器非常聪明。在循环中使用构造函数时,不会每次都创建对象,因为编译器知道它是相同的。而且它非常方便,因为这样,如果对象Q没有在循环外使用,您可以专注于干净的代码、范围等,建议在循环内声明它。
for(int i = 0; i < 1000000; ++i) {
GaussQuadrature<double> Q(N, func, a, b); // some arguments
Q.Quadrature();
std::cout << "address: " << &Q << "\n";
}
ctor
address: 0x7fff23059400
ctor
address: 0x7fff23059400
.
.
.
ctor
address: 0x7fff23059400
clock_t tic = clock();
for(int i = 0; i < 1000000; ++i) {
GaussQuadrature<double> Q(N, func, a, b);
Q.Quadrature();
}
float elapsed = (clock() - (float)tic) / CLOCKS_PER_SEC;
std::cout << std::setprecision(10) << "time: " << elapsed << "\n";
time: 12.47999954
clock_t tic = clock();
GaussQuadrature<double> Q(N, func, a, b);
for(int i = 0; i < 1000000; ++i) {
Q.Quadrature();
}
float elapsed = (clock() - (float)tic) / CLOCKS_PER_SEC;
std::cout << std::setprecision(10) << "time: " << elapsed << "\n";
time: 12.65999985