I have some functions that are being called a lot. Inside each function, local variables are constructed. These variables are usually Eigen::MatrixXd
s that are sort of small (usually under 10 x 10). Every call constructs the same variable, over and over again, then discards it.
I started thinking it would be faster to define these variables outside of the function, and then look them up.
I started off with these three files.
First: functions.h
#ifndef FUNCTIONS_H
#define FUNCTIONS_H
#include <Eigen/Dense>
Eigen::MatrixXd getMatrix();
#endif //FUNCTIONS_H
second: 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;
}
Third, main.cpp
#include "functions.h"
int main()
{
for(int i = 0; i < 500000; ++i)
getMatrix();
return 0;
}
First, functions2.h
:
#ifndef FUNCTIONS2_H
#define FUNCTIONS2_H
#include <Eigen/Dense>
extern const Eigen::MatrixXd myMatrix;
Eigen::MatrixXd getMatrix2();
#endif //FUNCTIONS2_H
then functions2.cpp
#include "functions2.h"
const Eigen::MatrixXd myMatrix = Eigen::MatrixXd::Identity(2,2);
Eigen::MatrixXd getMatrix2()
{
return myMatrix;
}
then a different main.cpp
#include "functions2.h"
int main()
{
for(int i = 0; i < 500000; ++i)
getMatrix2();
return 0;
}
If your get
functions will always be returning the same matrix, you can generate it once the first time it is needed, without using a global variable, by using a static local one.
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;
}
This uses a lambda function to initialize the matrix, rather than another function. It will also create a copy of the matrix every time, but the original matrix is hidden from all users and cannot be changed. Copy elision cannot happen here, since the source is not a non-static local variable. RVO can still be done.
Another option here is to return a reference to the matrix, by changing the function to
const &Eigen::MatrixXd getMatrix()
This will avoid the copy and still hides the original matrix from changes unless the caller applies a const_cast
to the returned value.
For getMatrix2
, you can just move the global variable you have into getMatrix2
as a static.