QMap:: contains() VS QMap:: find()

Я часто вижу код вроде:

if(myQMap.contains("my key")){
    myValue = myQMap["my key"];
}

который теоретически выполняет два поиска в QMap.

Моя первая реакция заключается в том, что она должна быть заменена следующей, которая выполняет только один поиск и должна быть в два раза быстрее:

auto it = myQMap.find("my key");
if(it != myQMap.end()){
    myValue = it.value();
}

Мне интересно, автоматически ли QMap делает эту оптимизацию для меня? Другими словами, мне интересно, сохраняет ли QMap позицию последнего элемента, найденного с помощью QMap:: contains(), и сначала проверяет его перед выполнением следующего поиска?

Спасибо!

Ответ 1

Я бы ожидал, что QMap предоставляет обе функции для лучшего интерфейса с классом. Естественно спросить, содержит ли карта "значение" с указанным ключом, чем вызов функции "найти".

Как показывает код, оба find и contains вызывают следующую внутреннюю функцию: -

Node *n = d->findNode(akey);

Итак, если вы собираетесь использовать возвращенный итератор, то использование find и проверка возвращаемого значения будет более эффективным, но если вы просто хотите знать, существует ли значение на карте, то вызов содержит лучше для удобства чтения.

Если вы посмотрите на исходный код, вы увидите, что QMap реализован как двоичная древовидная структура узлов. Вызов findNode выполняет итерацию через узлы и не кэширует результат.

Ответ 2

Исходный код QMap показывает, что нет специального кода в методе QMap::contains().

В некоторых случаях вы можете использовать QMap::value() или QMap::values(), чтобы получить значение для ключа и проверить, правильно ли оно. Эти методы (и const operator[]) скопируют значение, хотя это, вероятно, нормально для большинства типов Qt, поскольку их базовые данные копируются на запись (особенно QMap).