2013-11-13 2 views
10

Я часто встречаю подобный код:QMap :: содержит() VS QMap :: найти()

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(), и проверяет его прежде, чем выполнить следующий поиск?

Спасибо!

+3

Уверен, что это не так. Вы можете использовать ту же самую константу QMap из нескольких потоков, что может вызвать серьезные проблемы, если она кэширует что-либо (и даже в лучшем кэшировании будет работать только для одного потока) – BeniBela

+1

Вот исходный код 'QMap': https: // qt .gitorious.org/qt/qt/source/57756e72adf2081137b97f0e689dd16c770d10b1: src/corelib/tools/qmap.h его нетривиально читать, но он должен помочь вам получить ответ, если вы действительно этого хотите. – Yakk

+0

@BeniBela Я бы ожидал, что в большинстве случаев QMap будет доступен из одного потока, поэтому, если оптимизация работает только для одного потока, все равно стоит его реализовать. – nbilal

ответ

4

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

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

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

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

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

+0

Откуда вы знаете, что findNode (akey) не выполняет собственно кэширование? if (akey == lastKey) {return lastNode;} – nbilal

+1

@nbilal, пожалуйста, исправьте меня, если я ошибаюсь, но, глядя на исходный код, похоже, что это не так. – TheDarkKnight

+0

Я бы не спросил здесь, знаю ли я ответ :) Вы наполовину ответили на мой вопрос, может быть, вы сможете улучшить свой ответ, объяснив и давая какое-то доказательство того, что findNode сам не делает кеширования. Благодарю. – nbilal

2

QMap исходный код показывает, что есть no special code в QMap::contains() метод.

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

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