время поиска unordered_map в c ++

0

У меня есть две разные реализации одной и той же функции

IPAddress UMNS::lookup(const HostName& name) const{
    auto it=ns.find(name);
    if(it!=ns.end()){
        return (*it).second;
    }
    return NON_EXISTING_ADDRESS;

}

а также

IPAddress UMNS::lookup(const HostName& name) const{

    auto it=find_if(ns.begin(),ns.end(),
        [&name] ( const pair<HostName,IPAddress> &a){ return a.first==name;});
    bool found = it != ns.end();
    if ( found ){
        return (*it).second;
    }
    return NON_EXISTING_ADDRESS;

}

ns является unordered_map но время выполнения двух функций не одинаково.

Первая реализация дает следующее:
Кол-во запросов: 1000000
Среднее время поиска (мс): 0,000373

Вторая реализация дает следующее:
Кол-во запросов: 1000000
Среднее время поиска (мс): 24,9

Что случилось со второй реализацией?
Почему я не могу использовать find_if?

  • 0
    Поскольку find_if , вероятно, не учат работать с unordered_map и поэтому просто использует линейный поиск по сравнению с поиском по хешу O (1). Также вопрос качества, тьфу. :-D
Теги:
stl

4 ответа

6

find_if ничего не знает о том, является ли find_if им последовательность контейнером, не говоря уже о том, предлагает ли этот контейнер оптимизированный способ выполнения одной и той же задачи. Он будет перебирать последовательность, которую он дал, применяя предикат, данный ему, который (для большого контейнера) будет намного медленнее, чем поиск на основе хэшей, предоставляемый функцией собственного find контейнера.

  • 0
    но если бы это была карта, а не неупорядоченная карта, это имело бы какое-то значение?
  • 1
    @ user2975699: find_if все еще будет перебирать карту и применять ее предикат; он до сих пор ничего не знает о контейнерах. map::find (возможно) будет несколько медленнее, чем unordered_map::find так как он выполняет поиск в логарифмическом времени, а не поиск по хешу.
3

std::find_if предназначен для работы с любыми Итераторами ввода, которые могут поступать из других контейнеров, таких как std::vector. Чтобы найти элемент в общих контейнерах, подобных этому, ему необходимо выполнить линейный поиск по всем элементам, пока не найдет тот, который он ищет. С другой стороны, элемент find std::unordered_map разработан специально для этого контейнера и способен находить элементы в среднем постоянном времени.

1

find_if - это наименее универсальная версия, которая не использует внутреннюю структуру контейнера или порядок. Таким образом, он использует обычный поиск O (n). С членом find вы получаете O(1) поиск, так как unordered_map реализован в виде хэш - таблицы.

1

find_if должен просматривать каждую запись на карте, пока не найдет ту, которую вы ищете, потому что она не знает, что вторая реализация эквивалентна первой, потому что она не может видеть внутри предиката, который вы ему даете (и компилятор не может его оптимизировать).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню