查找全局变量而不是在 C++ 函数中构造它们
Looking up global variables instead of constructing them inside a c++ function
问题:
我有一些函数被称为 lot。在每个函数内部,构造局部变量。这些变量通常是 Eigen::MatrixXd
s,它们有点小(通常小于 10 x 10)。每次调用都构造相同的变量,一遍又一遍,然后丢弃它。
我开始认为在函数外定义这些变量会更快,然后查找它们。
- 为什么某些全局变量的 "looking up" 可能比一遍又一遍地重新构造它更快?
- 我应该将全局常量放在命名空间中吗?这种方法会出什么问题?
第一个代码:
我从这三个文件开始。
第一个: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秒。如果你写一次,使用一个全局变量或 main 中的一个变量,然后你读取它 N 次,这需要 1 + N*1 秒。如果每次要使用对象时都重新创建对象,这需要 2*N 秒。
将常量放在对它们有意义的名称空间中可能是一个很好的设计决策。例如,也许你会把 "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
中。
问题:
我有一些函数被称为 lot。在每个函数内部,构造局部变量。这些变量通常是 Eigen::MatrixXd
s,它们有点小(通常小于 10 x 10)。每次调用都构造相同的变量,一遍又一遍,然后丢弃它。
我开始认为在函数外定义这些变量会更快,然后查找它们。
- 为什么某些全局变量的 "looking up" 可能比一遍又一遍地重新构造它更快?
- 我应该将全局常量放在命名空间中吗?这种方法会出什么问题?
第一个代码:
我从这三个文件开始。
第一个: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秒。如果你写一次,使用一个全局变量或 main 中的一个变量,然后你读取它 N 次,这需要 1 + N*1 秒。如果每次要使用对象时都重新创建对象,这需要 2*N 秒。
将常量放在对它们有意义的名称空间中可能是一个很好的设计决策。例如,也许你会把 "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
中。