微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

我的程序中有以下代码.

//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将是无效的标识符,因为它是为实现保留的.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐