各ステップで dy/dx を評価し、その後は必要ない ODE インテグレーターを作成しています。新しいdydxベクトルの割り当てに時間を費やさないように、スペースのみを割り当ててそのスペースを使用する方が速いようです。コンパイラはこれを最適化しますか? 言い換えれば、どちらが優れていますか?
1)
vector<double> dydx(const vector<double>&x) {
vector<double> dydx_tmp(x.size());
for(size_t i = 0; i < x.size()/2; ++i) {
dydx_tmp[2*i] = -x[2*i+1];
dydx_tmp[2*i+1] = x[2*i];
}
return dydx_tmp;
}
または 2)、dydx が既に割り当てられており、更新が必要な場合
void update_dydx(vector<double> & dydx, const vector<double> &x) {
for(size_t i = 0; i < x.size()/2; ++i) {
dydx[2*i] = -x[2*i+1];
dydx[2*i+1] = x[2*i];
}
}
3)の場合もある
vector<double> dydx_by_v(vector<double> x) {
vector<double> dydx_tmp(x.size());
for(size_t i = 0; i < x.size()/2; ++i) {
dydx_tmp[2*i] = -x[2*i+1];
dydx_tmp[2*i+1] = x[2*i];
}
return dydx_tmp;
}
これはhttp://cpp-next.com/archive/2009/08/want-speed-pass-by-value/に従いますが、この場合、x
のメモリは後で出力に使用されるため問題ありません。コンパイラの RVO では使用できません。