2009-11-12 11 views
1

J'utilise les algorithmes de tas STL C++, et j'ai écrit une classe wrapper pour pouvoir faire autre chose. Quand j'ai essayé d'utiliser le code ci-dessous, par exemple:Différence de vitesse: functor séparé VS operator() dans une grande classe avec * this

//! Min-heap wrapper class. 
class FMMHeap{ 
public: 
    FMMHeap(Vector &phi) : _phi(phi) {} 
    bool operator()(unsigned p1, unsigned p2) {return fabs(_phi(p1)) > fabs(_phi(p2)); } 
    inline void pop(){ pop_heap(_heap.begin(),_heap.end(),*this); _heap.pop_back(); } 
    [...lots of other stuff...] 
    vectorU32 _heap; 
    Vector &_phi; 
} 

Il était wayyyyy plus lent que quand j'avais un objet de fonction séparée comme ceci:

struct HeapSort{ 
public: 
    HeapSort(Vector &phi) : _phi(phi) {} 
    bool operator()(unsigned p1, unsigned p2) {return fabs(_phi(p1)) > fabs(_phi(p2)); } 
private: 
    Vector &_phi; 
}; 

class FMMHeap{ 
public: 
    FMMHeap(Vector &phi) : cmp(phi) {} 
    inline void pop(){ pop_heap(_heap.begin(),_heap.end(),cmp); _heap.pop_back(); } 
    [...lots of other stuff...] 
    vectorU32 _heap; 
    HeapSort cmp; 
} 

Je ne sais pas pourquoi. Est-ce que le ralentissement vient de * ceci parce que la classe a beaucoup de données? Cela semble étrange. Ou est-ce quelque chose à voir avec la façon dont l'objet fonction est utilisé?

+0

Vous devriez faire votre opérateur() const. Les prédicats ne devraient pas avoir d'effets secondaires. – sellibitze

Répondre

8

Je ne suis pas certain, mais peut-être pop_heap finit par copier l'objet foncteur vous passez La copie de votre FMMHeap serait plus cher que le simple HeapSort

+1

Oui, son passage de la fonction de comparaison objet par valeur. –

+0

Plus généralement, la plupart des algorithmes STL transmettent l'objet prédicat par valeur, il est donc préférable d'utiliser des objets séparés. –

0

Le plus grand speedup des conteneurs STL est. Inlining d'entre eux, de sorte que le compilateur peut travailler sur la façon de supprimer et de réorganiser les choses.

C'est une bonne supposition que le compilateur parvient à aligner le foncteur externe d'une manière que const propogation l'empêche de le faire dans la version lente.

Qu'advient-il de la version lente si l'opérateur bool est const?