加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 将对象传递给比较函数会使排序变慢?

发布时间:2020-12-16 10:12:37 所属栏目:百科 来源:网络整理
导读:我的程序中有以下代码. //Compare classclass SortByFutureVolume{public: SortByFutureVolume(const Graph _g): g(_g){} bool operator() (const Index lhs,const Index rhs){ return g.getNode(lhs).futureVolume() g.getNode(rhs).futureVolume(); } priv
我的程序中有以下代码.

//Compare class
class SortByFutureVolume
{
public:
        SortByFutureVolume(const Graph& _g): g(_g){}

        bool operator() (const Index& lhs,const Index& rhs){
            return g.getNode(lhs).futureVolume() > g.getNode(rhs).futureVolume();
        }
    private:
        Graph g;
};

然后我用它来进行排序:

std::sort(nodes.begin(),nodes.end(),SortByFutureVolume(g));

当我在我的mac计算机上运行上面的代码以获得大小为23K的向量时,它会在几秒钟内完成.但是,当我在我的ubuntu 14机器上运行时.它需要几分钟,甚至还没有完成.

我搜索这个问题,在这里找到了以下解决方案Can I prevent std::sort from copying the passed comparison object

基本上修改我的代码,以解决问题:

SortByFutureVolume s(g);
std::sort(_nodes.begin(),_nodes.begin()+ end,std::ref(s));

在此之后,我的mac和ubuntu上的运行时具有可比性.非常快.

我知道这有效,但我想知道为什么?我知道上面的慢代码是由于复制了图形和SortByFutureVolume.你为什么需要std :: ref()?这个解决方案是否正确,是否有更好的方法来做到这一点?

解决方法

而不是在SortByFutureVolume中有一个Graph数据成员,你应该有一个Graph&或const图表&如果g可以只读.这样,只要复制SortByFutureVolume,就不会复制Graph.

class SortByFutureVolume
{
public:
        SortByFutureVolume(const Graph& _g): g(_g){}

        bool operator() (const Index& lhs,const Index& rhs){
            return g.getNode(lhs).futureVolume() > g.getNode(rhs).futureVolume();
        }
    private:
        Graph& g;
        // or
        const Graph& g;
};

正如Benjamin Lindley在注释中指出的那样,如果您更改SortByFutureVolume以存储指向Graph而不是refernece的指针,则SortByFutureVolume将变为可分配的副本,因为可以指定指针但引用不能.那会给你

class SortByFutureVolume
{
public:
        SortByFutureVolume(const Graph& _g): g(&_g){}

        bool operator() (const Index& lhs,const Index& rhs){
            return g->getNode(lhs).futureVolume() > g->getNode(rhs).futureVolume();
        }
    private:
        const Graph * g;
};

作为一个方面,不能将_g作为函数参数中的变量名称,因为它不以大写字母开头,但不使用前导下划线是一个好习惯.在全局空间中这是双重的,其中_g将是无效的标识符,因为它是为实现保留的.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读