ускорение std :: map и boost: unordered_map [] операция - PullRequest
0 голосов
/ 20 февраля 2012

У меня есть MAP, которая необязательно имеет тип std :: map и, необязательно, типа unordered_map (в соответствии с typdef MAP), и функция, которая добавляет значение к указанному ключевому значению:

  func1(MAP<string,  double>  &map, string  &key, double &val2add){
    try
{
      map.at(key)  += val2add;
}catch(out_of_range& oor){
          map[key] = val2add; // in case map[key] didn't exist before. 
    }
  }

Проблема в том, что это означает двойную (и, возможно, даже больше) работу, чем просто

  func2(MAP<string,  double>  &map, string  &key, double &val2add){
       map[key] += val2add; // if map[key] doesn't exist - problem
  }

Но вышеописанное не сработает, поскольку, как я понимаю, оператор [] инициализирует новый объект на карте с заданным ключом и двойным значением по умолчанию. Если бы я знал, что двойное значение по умолчанию равно 0, то func2 все равно достиг бы того, чего я хочу - но я не могу на это полагаться.

Так есть ли способ использовать [] лучше, чем func1?

Ответы [ 2 ]

7 голосов
/ 20 февраля 2012

Нет проблем со вторым фрагментом кода. Если ключ не найден, [] вставит инициализированный значением объект (в данном случае double со значением ноль) и вернет ссылку на него. Таким образом, в этом случае map[key] += value имеет тот же эффект, что и map[key] = value.

В общем, почти наверняка эффективнее вызвать find, а затем проверить результат, чем at и перехватить исключение. Реализации обработки исключений часто предполагают, что исключения создаются только в исключительных случаях, и оптимизируют обычный случай за счет необычного.

Конечно, скорость важна, тогда вам нужно измерить ее, чтобы быть уверенным.

2 голосов
/ 20 февраля 2012

Вы не можете сделать это с operator[], но вы можете использовать метод insert: он возвращает итератор и логическое значение, указывающее, указывает ли возвращаемый итератор на ранее существующий элемент или на вновь вставленный элемент.

Кроме того, примитивные типы по умолчанию инициализируются нулем.

...