Что такое повышение:: дополнительная эффективность?

У меня есть следующее:

class Obj;
typedef std::map<string, string> StrMap;
std::map<std::string, std::pair<Obj, StrMap> > complexMap;

Дело в том, что для некоторых записей в complexMap StrMap будет пустым, и я вообще не буду его использовать, поэтому для эффективности я собираюсь использовать boost:: необязательный. Мой вопрос заключается в том, какова эффективность повышения:: необязательно, я боюсь, что, заплатив его цену, я ничего не получу в конце.

3 ответа

Решение

Думать о optional как контейнер, который может содержать 0 или 1 значения. Ваша карта уже является контейнером, который может содержать от 0 до N элементов. Таким образом, необязательная карта - это контейнер в контейнере, который может содержать от 0 до N элементов. На самом деле, здесь нет никакой пользы.

Накладные расходы пустой карты довольно малы. Карты действительно построены из узлов карты внутри, и пустая карта просто не имеет никаких узлов. (Это не может быть, потому что каждый узел содержит значение, и нет способа, которым пустая карта могла бы создать значение по умолчанию)

Если вы делаете "разреженные" вычисления, вы можете сделать две вещи:

  1. держать большой complexMap содержащий множество несуществующих результатов с boost::optional, Это инкапсулирует разреженность для каждого элемента.
  2. создать дополнительный слой косвенности (unordered_map например), который содержит указатели на существующие элементы в вашем complexmMap, Это инкапсулирует разреженность для каждой отдельной карты.

Альтернатива 1 будет более удобной для вас, как для программиста, хотя и потребует немного времени за счет нехватки места. Альтернатива 2 будет почти идеально компактной и сохранит complexMap как можно меньше, но требует больше программирования заранее.

Выберите любую альтернативу, более приемлемую для вас (подсказка: если вы выполняете вычисления уровня гигабайта в complexMap, может быть, дополнительный уровень косвенности окупится, иначе я бы не стал беспокоиться).

Помимо космических накладных расходов, есть немного других затрат на boost::optional, поскольку он не требует конструктора по умолчанию или динамического выделения памяти.

Перемещение комментария к ответу...

Подумайте о том, как реализована опция, она обычно имеет некоторое внутреннее хранилище (чтобы позволить ему удерживать объект карты - как вы это делали в коде выше), и единственное отличие состоит в том, что он не создает карту в этом хранилище. - это осталось на потом. Однако необязательный объект должен быть построен. Так что теперь вместо того, чтобы просто строить карту, вы создаете больший необязательный объект в случае, когда вы не используете карту, и когда вы используете карту, вы должны создать это тоже. Похоже, вы делаете больше вещей для небольшой выгоды.

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

Отказ от ответственности: Но, как и во всех вопросах, связанных с производительностью, профиль, профиль, а затем профиль снова...

Другие вопросы по тегам