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;istd::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]);
}