Повышение производительности любого _диапазона :стандартного ::предыдущего (итератора )по сравнению с --итератором

Недавно я начал предпочитать бесплатные функции std::nextи std::prevявному копированию и увеличению/уменьшению итераторов. Теперь я наблюдаю странное поведение в довольно конкретном случае, и я был бы признателен за любую помощь в его прояснении.

У меня есть функция интерполяции/экстраполяции, работающая с boost::any_rangeнекоторых X_type. Полное определение типа диапазона::

boost::any_range <
    const X_type,
    boost::random_access_traversal_tag,
    const X_type,
    std::ptrdiff_t
>

any_range, в данном конкретном случае, назначается из iterator_range, содержащего два указателя на const X_type, который служит представлением X_typeпримерно половины области data()объекта vector<char>.

Компилирую свое приложение в MSVC 2010, все отлично работает. При компиляции того же кода в MinGW g++ 4.7.0 он, похоже, зависал в одном конкретном месте, которое я затем сузил до этого (, слегка сокращенного):

// Previously ensured conditions:
// 1) xrange is nonempty;
// 2) yrange is the same size as xrange.

auto x_equal_or_greater =
    std::lower_bound(std::begin(xrange),std::end(xrange),xval);

if (x_equal_or_greater == std::end(xrange))
{
    return *yit_from_xit(std::prev(x_equal_or_greater),xrange,yrange);
}

Пройдясь по коду в gdb, я обнаружил, что он не зависает, просто требуется очень много времени для возврата из единственного std::prevвызова -, который в libstdc++ реализован в терминах std::advanceи, в конечном счете, +=оператор.

Просто заменив строку returnна:

auto xprev=x_equal_or_greater;
--xprev;
return *yit_from_xit(xprev,xrange,yrange);

Производительность снова отличная, и задержки практически нет.

Я знаю о накладных расходах при использовании итераторов типа -стираемых (итераторовany_range), но даже так,действительно ли два приведенных выше случая влекут за собой такие разные затраты? Или я что-то не так делаю?

9
задан motiz88 1 July 2012 в 10:58
поделиться