C++ 比较向量中的元素时所用的时间呈指数增长
我有一段代码如下所示:C++ 比较向量中的元素时所用的时间呈指数增长,c++,performance,vector,montecarlo,C++,Performance,Vector,Montecarlo,我有一段代码如下所示: void MonteCarloRainbowOptionFunction::ValueInstrument() { std::vector<MJArray> correlatedNormVariates = GetArraysOfCorrelatedGauassiansByBoxMuller(numberOfPaths, covMatrix); std::vector<StatisticAllPaths> thesePathGat
void MonteCarloRainbowOptionFunction::ValueInstrument()
{
std::vector<MJArray> correlatedNormVariates = GetArraysOfCorrelatedGauassiansByBoxMuller(numberOfPaths, covMatrix);
std::vector<StatisticAllPaths> thesePathGatherers;
for (unsigned long i = 0; i < S_vect.size(); i++)
{
StandardExcerciseOption thisOption(ThePayOffVect[i], TTM);
StatisticAllPaths onePathGatherer;
thesePathGatherers.push_back(onePathGatherer);
OneStepMonteCarloValuation(thisOption, S_vect[i], impvol_vect[i], r, d_vect[i], numberOfPaths, correlatedNormVariates[i], thesePathGatherers[i]);
}
f = 0;
for (unsigned long i = 0; i < numberOfPaths; i++)
{
int count = 0;
if (i % 2500 == 0)
{
count += 1;
std::cout << i << " paths done" << "\n";
}
std::vector<double> outcomes;
for (unsigned long j = 0; j < S_vect.size(); j++)
{
outcomes.push_back(thesePathGatherers[j].GetResultsSoFar()[0][i]);
}
switch (optionType)
{
case RainbowOptionType::best_of:
f += *max_element(outcomes.begin(), outcomes.end());
break;
case RainbowOptionType::worst_of:
f += *min_element(outcomes.begin(), outcomes.end());
break;
default:
throw std::runtime_error("Unsupported or unknown option type found in " + GetuniqueIdentifier()[0]);
break;
}
}
f *= ((double)nominal/numberOfPaths);
return;
}
void Montecarlo InbowOptionFunction::ValueInstrument()
{
std::vector CorrelatedNormavariates=GetArraySof CorrelatedGaussiansByBoxmller(路径数,covMatrix);
std::矢量路径采集器;
for(无符号长i=0;i std::cout那么,您正在复制您的结果列表向量4次,这没有帮助
std::vector<std::vector<double>> StatisticAllPaths::GetResultsSoFar() const
{
vector<double> innerVector(ResultList); //first copy
vector<vector<double> > Results(1, innerVector); //second copy
Results[0] = ResultList;// third copy
return Results;// return by value = fourth copy
}
std::vector StatisticallPath::GetResultsOfar()常量
{
vector innerVector(ResultList);//第一次拷贝
向量结果(1,innerVector);//第二次复制
结果[0]=ResultList;//第三份副本
返回结果;//按值返回=第四个副本
}
最好通过引用传递向量并填充它:
void StatisticAllPaths::GetResultsSoFar(std::vector<std::vector<double>> & result ) const
{
result.clear(); //discard the current contents if any
result.push_back(ResultList); //one copy
}
void statisticallpath::GetResultsSoFar(std::vector&result)const
{
result.clear();//丢弃当前内容(如果有)
result.push_back(ResultList);//一份
}
希望这能有所帮助这里有一些答案,重点是在getResultsOfar
中发生的过度复制,但没有一个能解决调用此函数的无意义问题:
std::vector<double> outcomes;
for (unsigned long j = 0; j < S_vect.size(); j++)
{
outcomes.push_back(thesePathGatherers[j].GetResultsSoFar()[0][i]);
}
当然,循环随后将以路径采集器[j].GetResultList()[i]
的形式访问第i个值。这里的关键区别是根本没有发生复制
对于结果
,还有一个小的优化。因为您确切地知道要推多少项,所以应该提前保留内存
i、 e
std::向量结果;
结果.储备(S_vect.size());
for(无符号长j=0;j
如果您希望它更简洁,请考虑定义<代码>双GETREST(SiZeHT)const < /C> >,它只返回一个结果,然后调用<代码> SeaStAsHealths[j]。GetResult(i)
我认为第四个副本可能会有争议,因为几乎所有正常的编译器都会通过RVO删除副本。@paddy啊,我明白了,也许最好在循环外调用一次GetResultsOfar并存储所有元素,而不是每次在循环内调用它只检索一个元素?我编辑了我的注释以重新编辑移动它,因为我意识到在循环的每个部分中对不同的对象调用了getResultsOfar
。但是,由于您只获得一个值,所以请求每个值的向量的完整向量没有多大意义。您好,很抱歉响应太晚,但我已经修复了您现在创建的只返回一个值的函数value by const reference,如您所说:constdouble&statisticallpath::GetOneValueFromResultsOfar(无符号长索引)const{return ResultList[index];}
现在代码运行速度可能快了1000倍(字面上)。非常感谢您的帮助
std::vector<std::vector<double>> StatisticAllPaths::GetResultsSoFar() const
{
vector<double> innerVector(ResultList); //first copy
vector<vector<double> > Results(1, innerVector); //second copy
Results[0] = ResultList;// third copy
return Results;// return by value = fourth copy
}
void StatisticAllPaths::GetResultsSoFar(std::vector<std::vector<double>> & result ) const
{
result.clear(); //discard the current contents if any
result.push_back(ResultList); //one copy
}
std::vector<double> outcomes;
for (unsigned long j = 0; j < S_vect.size(); j++)
{
outcomes.push_back(thesePathGatherers[j].GetResultsSoFar()[0][i]);
}
const std::vector<double>& StatisticAllPaths::GetResultList() const
{
return ResultList;
}
std::vector<double> outcomes;
outcomes.reserve(S_vect.size());
for (unsigned long j = 0; j < S_vect.size(); j++)
{
outcomes.push_back(thesePathGatherers[j].GetResultList()[i]);
}