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

时间:2017-04-05 17:03:52

标签: c++ global-variables extern

问题:

我有一些被称为批次的功能。在每个函数内部,构造局部变量。这些变量通常是Eigen::MatrixXd s,有点小(通常低于10 x 10)。每次调用都会一遍又一遍地构造同一个变量,然后将其丢弃。

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

  1. 为什么某个全局变量的“查找”可能比一遍又一遍地重新构建它更快?
  2. 我应该将全局常量放在命名空间中吗?这种方法可能出现什么问题?
  3. 第一个代码:

    我开始使用这三个文件。

    首先: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;
    }
    

3 个答案:

答案 0 :(得分:3)

如果您的get函数将始终返回相同的矩阵,则可以在第一次需要时生成它,而不使用全局变量,使用静态本地变量。

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函数初始化矩阵,而不是另一个函数。它还会每次创建矩阵的副本,但原始矩阵对所有用户都是隐藏的,无法更改。复制省略不能在这里发生,因为源不是非静态局部变量。 RVO仍然可以完成。

此处的另一个选项是通过将函数更改为

来返回对矩阵的引用
const &Eigen::MatrixXd getMatrix()

除非调用者将const_cast应用于返回值,否则这将避免复制并仍然隐藏原始矩阵。

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

答案 1 :(得分:1)

一般

  1. 假设将矩阵写入内存需要1秒钟,并且需要一秒钟才能读取矩阵。如果您使用全局变量或main中的变量编写一次,并且您读取它N次,则需要1 + N * 1秒。如果每次要使用它时都重新创建对象,则需要2 * N秒。

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

答案 2 :(得分:1)

Globals可能更慢。

这可能有点意外,但通常以干净的纸张开始便宜。 Globals的缺点是所有代码都可以改变它们,这可能会妨碍优化。