C++ 为什么在类实例化期间没有CPU消耗?

C++ 为什么在类实例化期间没有CPU消耗?,c++,C++,我创建了一个循环,它实例化了一个类10亿次,并且非常惊讶地发现,根据Windows任务管理器,它只运行了0毫秒,并且没有消耗CPU时间 正如您从下面的代码中看到的,我显然没有使用默认构造函数做任何事情,但是我假设会有一个重大的CPU问题,创建然后一次又一次地销毁这个类。有人能解释为什么没有明显的CPU损坏吗 class Cmytest { public: int lookup(); bool create_rec(); bool delete_rec(); }; void tes

我创建了一个循环,它实例化了一个类10亿次,并且非常惊讶地发现,根据Windows任务管理器,它只运行了0毫秒,并且没有消耗CPU时间

正如您从下面的代码中看到的,我显然没有使用默认构造函数做任何事情,但是我假设会有一个重大的CPU问题,创建然后一次又一次地销毁这个类。有人能解释为什么没有明显的CPU损坏吗

class Cmytest {
public:
  int  lookup();
  bool create_rec();
  bool delete_rec();
};

void test() {
  for (int i=0; i<1000000000; i++) {
    Cmytest mytest;
  }
}

int main()
{
  test();
  return 0;
}
然后我在循环中调用它:

int iter=0;
void test() {
  for (int i=0; i<1000000000; i++) {
    Cmytest mytest;
    mytest.count(iter);
  }
}
int iter=0;
无效测试(){
对于(int i=0;i,在“假设规则”下,允许编译器以任何方式转换您的程序,以使可观察到的副作用保持不变†。您的程序除了返回
0
,没有可观察到的副作用,因此几乎整个程序都可以解析为零

即使我们忽略了这一点,当对象在循环中声明时,编译器通常会反复使用同一对象,而不必重新分配内存(但需要重新初始化对象)。在本例中,编译器可能甚至可以看到对象保持不变,并且可以在无需重新初始化的情况下重新使用。无论如何,您的类没有要初始化的状态

为了演示,如果我编译代码时最大程度地优化了代码,那么
test
函数的结果程序集如下所示:

_Z4testv:
    .cfi_startproc
    ret
它马上就回来了

†复制省略是一种明确允许的优化,即使它确实修改了程序的可观察副作用。

根据“假设规则”,编译器允许以任何方式转换您的程序,使可观察到的副作用保持不变†。您的程序除了返回
0
,没有可观察到的副作用,因此几乎整个程序都可以分解为零

即使我们忽略了这一点,当对象在循环中声明时,编译器通常会反复使用同一对象,而不必重新分配内存(但需要重新初始化对象)。在本例中,编译器可能甚至可以看到对象保持不变,并且可以在无需重新初始化的情况下重新使用。无论如何,您的类没有要初始化的状态

为了演示,如果我编译代码时最大程度地优化了代码,那么
test
函数的结果程序集如下所示:

_Z4testv:
    .cfi_startproc
    ret
它马上就回来了



†复制省略是一种明确允许的优化,即使它确实修改了可观察到的程序副作用。

根据编译器和您传递给它的标志,它可能会决定优化没有效果的代码。在这种情况下,您声明了一个从未使用过的变量,因此编译器决定使用它是安全的优化此代码,使其永远不会执行。

根据编译器和传递给它的标志,它可能决定优化无效的代码。在这种情况下,您声明一个从未使用过的变量,因此编译器决定安全地优化此代码,使其永远不会执行。

编译器可以优化编译器说:“这里什么也没发生,让我们把这个循环扔掉。”.
Cmytest mytest;
只要没有任何副作用,任何一个像样的编译器都可以对其进行优化。有人提到过它被优化掉了吗?你打印了汇编代码吗?真相就在汇编代码中。如果没有明显的效果,编译器可以优化循环。编译器说:“这里什么也没发生,我们把这个环扔掉吧".
Cmytest mytest;
只要没有任何副作用,任何一个像样的编译器都可以对此进行优化。有人提到过它被优化掉了吗?你打印了汇编代码吗?真相在汇编代码中。不确定最后一次编辑。它在堆栈上,很容易分配。例如,如果它是
std::string
,它将在每次迭代中重新分配动态内存。@NeilKirk我只是试图避免使用堆栈/堆术语,但是的,在一般情况下仍需要进行销毁和初始化。@JosephMansfield,在运行上述测试之前,我打算将Cmytest设为动态,并在程序逻辑证明该类将需要。这就是为什么我对结果如此惊讶的原因。我认为如果不动态地进行操作,会浪费ram和cpu,但我认为我错了。看起来确实在堆栈上创建类很好。你同意吗?再次感谢。@CarolineBeltran如果有任何问题,动态分配会更慢(从操作系统和间接寻址请求内存).关于每个循环迭代中ctor+dtor的省略:只有编译器知道它们没有明显的副作用时,这才有效,就像这里一样。不确定最后一次编辑。它在堆栈上,很容易分配。例如,如果它是
std::string
,它将在每次迭代中重新分配动态内存。@NeilKirk I只是tr“我想避免使用堆栈/堆术语,但是的,在一般情况下仍然需要进行销毁和初始化。@JosephMansfield,在运行上述测试之前,我打算使Cmytest动态化,并在程序逻辑证明需要该类后才实例化它。这就是为什么我对结果如此惊讶的原因。我想如果不动态执行,我会浪费ram和cpu,但我认为我错了。在堆栈上创建类看起来确实不错。你同意吗?再次感谢。@CarolineBeltran如果有任何问题,动态分配会更慢(从操作系统请求内存和间接寻址).关于省略每个循环迭代的ctor+dtor:只有当编译器知道它们没有明显的副作用时,这才有效,就像这里一样。