У меня есть следующее:
class Obj;
typedef std::map<string, string> StrMap;
std::map<std::string, std::pair<Obj, StrMap> > complexMap;
Дело в том, что для некоторых записей в complexMap StrMap будет пустым, и я вообще не буду его использовать, поэтому для эффективности я собираюсь использовать boost :: необязательный. Мой вопрос в том, какова эффективность повышения: необязательно, я боюсь, что, заплатив его цену, я ничего не получу в конце.
Думать о optional
как контейнер, который может содержать 0 или 1 значения. Ваша карта уже является контейнером, который может содержать от 0 до N элементов. Поэтому необязательная карта — это контейнер-контейнер, который может содержать от 0 до N элементов. На самом деле, здесь нет никакой пользы.
Накладные расходы пустой карты довольно малы. Карты действительно построены из узлов карты, и на пустой карте просто нет узлов. (Это не может быть, потому что каждый узел содержит значение, и нет способа, которым пустая карта могла бы создать значение по умолчанию)
Перемещение комментария к ответу …
Подумайте о том, как реализована опция, она обычно имеет некоторое внутреннее хранилище (чтобы он мог удерживать объект карты — как вы это делали в коде выше), и единственное отличие состоит в том, что он не создает карту в этом хранилище. — это осталось на потом. Однако необязательный объект должен быть построен. Так что теперь вместо того, чтобы просто строить карту, вы создаете больший необязательный объект в случае, когда вы не используете карту, и когда вы используете карту, вы должны создать это тоже. Похоже, вы делаете больше вещей для небольшой выгоды.
Есть случаи, когда optional
имеет смысл (например, возвращаемые значения, когда вы хотите указать недопустимое состояние, например, или у вас есть очень дорогой конструктор, который выполняет много инициализации сложных элементов), для объектов с тривиальными конструкторами необязательный код действительно не стоит кода загромождали.
Отказ от ответственности: Но, как и во всех вопросах, связанных с производительностью, профиль, профиль, а затем профиль снова …
Если вы делаете «разреженные» вычисления, вы можете сделать две вещи:
complexMap
содержащий множество несуществующих результатов с boost::optional
, Это заключает в себе разреженность на за элемент основа.unordered_map
например, который содержит указатели на существующие элементы в вашем complexmMap
, Это заключает в себе разреженность на за карту основа.Альтернатива 1 будет более удобной для вас, как для программиста, хотя и потребует немного времени за счет нехватки места. Альтернатива 2 будет почти идеально компактной и сохранит complexMap
как можно меньше, но требует больше программирования заранее.
Выберите любую альтернативу, более приемлемую для вас (подсказка: если вы выполняете вычисления уровня гигабайта в complexMap
Возможно, дополнительный уровень косвенности окупится, иначе я бы не стал беспокоиться).
Кроме космических накладных расходов, есть немного других затрат на boost::optional
, поскольку он не требует конструктора по умолчанию или динамического выделения памяти.