巨大的性能下降 - 向量问题?

Posted

技术标签:

【中文标题】巨大的性能下降 - 向量问题?【英文标题】:Huge performance slowdown - vectors the problem? 【发布时间】:2011-06-28 17:53:11 【问题描述】:

我的这部分代码旨在获取Tile 对象的不规则形状轮廓,并循环创建一个环并降低环中瓷砖的高度值,同时每次扩展环以包含这些瓷砖在前一个环之外(这有意义吗?)。然而,我发现我的性能大幅下降,每个循环都比之前的循环慢得多。为什么会这样?

我在想这可能是因为 oldEdge = theEdge; 和类似的行(两者都是向量,我将一个分配给另一个)。但即便如此,我也不理解巨大的性能下降。也许我正在做一些明显愚蠢的事情。谁能直截了当?

注意oldEdgetheEdgenewEdge都是vector<Tile*>s。

int decrease = 1;
while(decrease < 10)

    cout << "Trying to smooth!\n";
    //First, modify the new edge.
    int newHeight = 70 - decrease;
    cout << "Height at: " << newHeight << endl;
    for(int i = 0; i < newEdge.size(); ++i)
    
        newEdge[i]->SetHeight(newHeight);
    
    //Increment decrease.
    decrease += 1;
    //Set the oldEdge and theEdge variables.
    oldEdge = theEdge;
    theEdge = newEdge;
    newEdge.clear();
    //Finally, find the new edge.
    cout << "Finding new edge!\n";
    for(int i = 0; i < theEdge.size(); ++i)
    
        //cout << "Checking a tile's neighbors!\n";
        for(int j = 0; j < theEdge[i]->m_AdjacentTiles.size(); ++j)
        
            bool valid = true;
            //Is this neighbor in theEdge?
            //cout << "Is this neighbor in theEdge?\n";
            for(int k = 0; k < theEdge.size(); ++k)
            
                if(theEdge[i]->m_AdjacentTiles[j] == theEdge[k])
                
                    valid = false;
                    break;
                
            
            //If not, is it in oldEdge?
            if(valid)
            
                //cout << "Is this neighbor in oldEdge?\n";
                for(int k = 0; k < oldEdge.size(); ++k)
                
                    if(theEdge[i]->m_AdjacentTiles[j] == oldEdge[k])
                    
                        valid = false;
                        break;
                    
                
            
            //If neither, it must be valid for continued expansion.
            if(valid)
            
                newEdge.push_back(theEdge[i]->m_AdjacentTiles[j]);
            
        
    

【问题讨论】:

为什么是Tile* 而不是Tile?您是否尝试过更改swaps 的分配,因为您还是放弃了newEdge 你有一个 3 嵌套循环。首先看看最里面的循环。示例:theEdge[i]-&gt;m_AdjacentTiles[j] 可以移出循环。 (不要指望编译器来做。)另外,我会倒计时,如for(int k = theEdge.size(); valid &amp;&amp; --k &gt;= 0;) 您能否大致了解您正在处理的size() 号码类型?并不是说它一定会影响逻辑,但它可以帮助指导优化的地方。 你试过分析代码了吗? 您写了“性能下降”和“性能下降”,但我找不到您来自哪里以及您所做的更改导致性能下降。 【参考方案1】:

据我所知,您的算法是O(n^2 * m) 的边数和相邻图块数。很可能只是小幅增加导致渐近性能爆炸,您会看到减速。如果对边缘容器进行了排序,您可以使用二分搜索,或者如果您能够对它们进行哈希处理,这也是一种选择。

我对您尝试使用的算法不够熟悉,但如果您应该使用完全不同的方法,您可能想重新审视一下。

【讨论】:

【参考方案2】:

不是向量,是算法。

你有一个三倍的嵌套循环。放入一些调试语句以找出它通过每个循环的次数。

【讨论】:

以上是关于巨大的性能下降 - 向量问题?的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL:具有多个运行功能而没有硬件瓶颈,性能下降

推力:sort_by_key 与 zip_iterator 性能

梯度下降算法

用于巨大“N”的 MATLAB Dftmtx

C++ 替代 C99 VLA(目标:保持性能)

从0开始的机器学习——梯度下降法