【问题标题】:more efficient to create static local objects c++更有效地创建静态本地对象 c++
【发布时间】:2013-08-16 23:38:22
【问题描述】:

编辑: 我知道在循环体之前声明一个对象效率更高,因为它在每次函数调用时调用构造函数和析构函数,而不是每次循环迭代一次。假设由于这个原因,类型 A 的对象在循环体之外更有效。

我想知道以下是否

void foo()
{
    static A var;  //A is a class with a constructor
    ...   //stuff done with var
}

更有效率
void foo()
{
    A var;   //A is a class with a constructor
    ...  //stuff done with var
}

因为前者会调用 A 的构造函数和析构函数一次,而不是后者每次调用 foo 都会调用一次。我通常在所有本地对象中问这个问题。

【问题讨论】:

    标签: c++ object constructor local-variables


    【解决方案1】:

    首先,它在语义上是不同的。你在比较两个不同的东西。如果您不关心语义差异,则任何一个都可以比另一个更快。如果A 的构造没有做太多,例如,仅仅初始化一个int,那么第二个版本很可能更快,例如,因为编译器需要知道它是否在运行时初始化var,并且在 C++11 中,初始化是线程安全的。如果A 的构造有点涉及,那么第一个版本可能更快。

    找出任何给定应用程序的唯一方法是测量。

    【讨论】:

    • 一般来说,如果构造函数不会对其余对象的使用产生影响,那么第一个会更好(如果构造函数足够大)
    • @bathtub 不,这不是重要的区别。
    【解决方案2】:

    经验法则:按您的意思编码(本地对象还是逻辑上需要在每次调用时共享?)并让编译器担心优化。

    我对非平凡类型的常量做了一个例外。例如,'static const std::string' 比 'const std::string' 更好,因为它每次都保存动态分配。但是,如果对象不包含动态分配,并且大小不是几十个字节,则将其设为局部变量。

    出于效率原因,没有必要将基本类型(例如const intconst char *const)设为静态,尽管这不会有什么坏处。

    由于静态对象在线程之间共享,编译器可能需要在每次需要使用它时检查它是否没有被另一个线程更新,而对于局部变量则不能这样。所以不要假设静态将是“最快的”。 (其工作原理取决于您的编译器实现)

    当然,您还需要了解是否将其设为静态可能会改变程序的行为。我上面的信息假设选择不会。

    【讨论】:

    • 因此,每次调用静态时使用的常量更有效。基本上,我在处理充当临时对象的对象时会这样做,这些对象稍后将被推送到向量或类似的东西。在循环中,在循环体之外构造比每次迭代更有效。所以我认为同样适用于这种情况
    • @bathtub 我不会担心的。如果太慢,可以稍后优化。最好先制定一个可行的解决方案。编译器也可以优化很多东西(特别是如果 A 很简单),所以无论如何它可能不会有什么不同。我的意思是它可能,但等到它重要。
    【解决方案3】:

    先做对,再做快。带有静态变量的版本会继承上一次调用的值;除非您需要在多次调用中保留信息,否则良好的设计要求将变量设置为已知状态,这就是构造函数所做的。如果您不使用构造函数,即,您将变量设为静态,那么您必须执行其他操作以使变量进入已知状态;也就是说,你最终调用了一个函数来完成构造函数所做的事情,但是你的语法更加晦涩。

    这是一个有点过于简单的例子:

    void f(int j) {
        static int i = 0;
        i = 0; // reset, because previous call left i with some spurious value
        while (i < j)
            std::cout << i << '\n';
    }
    

    除此之外,在调用之间共享该变量意味着在多线程程序中,您必须同步对该函数的所有调用,这会引入一个瓶颈,几乎可以肯定会抵消每次使用时不构造对象所带来的任何性能提升.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-03
      • 2017-12-10
      • 1970-01-01
      • 1970-01-01
      • 2020-04-22
      • 2016-04-27
      • 1970-01-01
      相关资源
      最近更新 更多