查找全局变量而不是在 C++ 函数中构造它们

Looking up global variables instead of constructing them inside a c++ function

问题:

我有一些函数被称为 lot。在每个函数内部,构造局部变量。这些变量通常是 Eigen::MatrixXds,它们有点小(通常小于 10 x 10)。每次调用都构造相同的变量,一遍又一遍,然后丢弃它。

我开始认为在函数外定义这些变量会更快,然后查找它们。

  1. 为什么某些全局变量的 "looking up" 可能比一遍又一遍地重新构造它更快?
  2. 我应该将全局常量放在命名空间中吗?这种方法会出什么问题?

第一个代码:

我从这三个文件开始。

第一个:functions.h

#ifndef FUNCTIONS_H
#define FUNCTIONS_H

#include <Eigen/Dense>

Eigen::MatrixXd getMatrix();

#endif //FUNCTIONS_H

秒:functions.cpp

#include "functions.h"

Eigen::MatrixXd getMatrix()
{
    Eigen::MatrixXd myMatrix(4,4);
    for(int i = 0; i < 4; ++i)
    {
        myMatrix(i,i) = 3.0;
    }
    return myMatrix;
}

三、main.cpp

#include "functions.h"

int main()
{

    for(int i = 0; i < 500000; ++i)
        getMatrix();

    return 0;
}

第二个代码:

首先,functions2.h

#ifndef FUNCTIONS2_H
#define FUNCTIONS2_H

#include <Eigen/Dense>

extern const Eigen::MatrixXd myMatrix;

Eigen::MatrixXd getMatrix2();

#endif //FUNCTIONS2_H

然后functions2.cpp

#include "functions2.h"

const Eigen::MatrixXd myMatrix = Eigen::MatrixXd::Identity(2,2);

Eigen::MatrixXd getMatrix2()
{
    return myMatrix;
}

然后是不同的 main.cpp

#include "functions2.h"

int main()
{

    for(int i = 0; i < 500000; ++i)
        getMatrix2();

    return 0;
}

一般

  1. 假设将矩阵写入内存需要1秒,读取需要1秒。如果你写一次,使用一个全局变量或 main 中的一个变量,然后你读取它 N 次,这需要 1 + N*1 秒。如果每次要使用对象时都重新创建对象,这需要 2*N 秒。

  2. 将常量放在对它们有意义的名称空间中可能是一个很好的设计决策。例如,也许你会把 "pi" 放在你的数学命名空间中。 Where should you put global constants in a C++ program?

全局变量很可能更慢。

这可能有点令人惊讶,但通常从干净的开始 sheet 很便宜。全局变量的缺点是所有代码都可能更改它们,这会妨碍优化。

如果您的 get 函数总是 return 同一个矩阵,您可以在第一次需要时生成它,而无需使用全局变量,而是使用静态局部变量.

Eigen::MatrixXd getMatrix()
{
   static Eigen::MatrixXd myMatrix{[](){
        Eigen::MatrixXd m(4,4);
        for(int i = 0; i < 4; ++i)
        {
            m(i,i) = 3.0;
        }
        return m;
    }};
    return myMatrix;
}

这使用 lambda 函数来初始化矩阵,而不是另一个函数。它还会每次创建矩阵的 copy,但原始矩阵对所有用户都是隐藏的,无法更改。此处不会发生复制省略,因为源不是非静态局部变量。 RVO还是可以做的。

此处的另一个选项是 return 对矩阵的引用,方法是将函数更改为

const &Eigen::MatrixXd getMatrix()

这将避免复制并仍然隐藏原始矩阵以防止更改,除非调用者将 const_cast 应用于 returned 值。

对于 getMatrix2,您可以将您拥有的全局变量作为静态变量移动到 getMatrix2 中。