2014-08-28 2 views
0

Я использую iterator_facade для обеспечения поддержки итератора для класса. Однако, поскольку iterator_facade :: dereference возвращается по ссылке, и это объект с возвращаемой нетривиальной копией-константой, моя производительность страдает от каждой разыменования (как профилируется VTune) в результате постоянного выполнения этих копии. Есть ли способ обойти это?Ускорение boost :: iterator_facade dereference

class time_series::iterator : public boost::iterator_facade< 
         time_series::iterator, 
         time_series::variable_vec, 
         boost::bidirectional_traversal_tag, 
         timestep> //<--- dereference type 
{ 
public: 
    iterator(); 
    iterator(const iterator& src); 
    ~iterator(); 
    iterator& operator=(const iterator& rhs); 
private: 
    //the following satisfies the reqs for a boost::facade bidirectional iterator 
    friend class boost::iterator_core_access; 
    friend class time_series; 

    const timestep& dereference() const; 
    bool equal(iterator const& other) const; 
    void increment(); 
    void decrement(); 
    std::ptrdiff_t distance_to(iterator const& other) const; 

    //iterators for the current step 
    timestep _currentStep;// <--returned on dereference, is non-trivial to copy. 
}; 

редактировать: согласно комментарию

const timestep& time_series::iterator::dereference() const 
{ 
    return _currentStep; 
} 
+0

Можете ли вы предоставить код для 'dereference()', 'increment()' и 'decment()'? –

ответ

5

Указано timestep вместо timestep& как Reference параметра шаблона, поэтому он постоянно делать копии. Измените его на timestep& или удалите вообще.

Также по какой-то причине вы храните _currentStep в итераторе по значению, что, вероятно, делает копии каждый раз, когда вы увеличиваете или уменьшаете.

Прочтите Boost tutorial on iterator_facade для справки о правильном использовании фасада.

+0

А, ладно. Итак, немой вопрос: если я сделаю это первое изменение, как мне получить доступ к методу в объекте, возвращаемом разыменованием? То есть timestep :: my_method()? – Chris

+2

@Chris Как в 'it-> my_method()' (что эквивалентно '(* it) .my_method()', разумеется скобки)? –

+0

@LucDanton да ... вот что я подумал. В этом примере _currentStep представляет собой оболочку вокруг tbb :: concurrent_hasmap, которая содержит итераторы в tbb :: concurrent_vector s. По сути, он перемещает итераторы в блокировку. Когда я делаю itr-> my_method(), я получаю ошибку компилятора, что 'my_method' не является членом tbb :: concurrent_vector. Который кажется ... причудливым. – Chris

Смежные вопросы