std::string
не делает копирование при записи. Раньше CoW был оптимизацией, но как только несколько потоков входят в изображение, это выходит за рамки пессимизации - это может замедлить код из-за огромных факторов. Это так плохо, что стандарт C ++ 0x активно запрещает это как стратегию реализации. Не только это, но вседозволенностьstd::string
изменчивых итераторов и ссылок на символы означает, что «запись» для std::string
влечет за собой почти каждую операцию.
Я полагаю, что оптимизация коротких строк составляет около 6 символов или что-то в этом регионе. Канаты не допускаются - std::string
должны хранить непрерывную память для c_str()
функции. Технически, вы могли бы поддерживать непрерывную нить и веревку в одном классе, но никто никогда не делал этого. Более того, из того, что я знаю о веревках, сделать их поточнобезопасными для манипуляции было бы невероятно медленно - возможно, так же плохо или хуже, чем CoW.
Ни один контейнер не выполняет выделение памяти, будучи объявленным в современных STL. Контейнеры на основе узлов, такие как list и map, использовали для этого, но теперь они имеют встроенную конечную оптимизацию и не нуждаются в ней. Обычно выполняется оптимизация, называемая «swaptimization», когда вы меняете местами пустой контейнер. Рассмотреть возможность:
std::vector<std::string> MahFunction();
int main() {
std::vector<std::string> MahVariable;
MahFunction().swap(MahVariable);
}
Конечно, в C ++ 0x это избыточно, но в C ++ 03 тогда, когда это обычно используется, если MahVariable выделяет память при объявлении, тогда это снижает эффективность. Я точно знаю, что это было использовано для более быстрого перераспределения контейнеров, таких какvector
в MSVC9 STL, что избавило от необходимости копировать элементы.
deque
использует что-то, что называется развернутым связанным списком. Это в основном список массивов, обычно в узле фиксированного размера. Таким образом, для большинства применений он сохраняет преимущества как смежного доступа к структурам данных, так и удаления амортизированного O (1), а также возможность добавления как к передней, так и к задней части, и лучшей аннулирования итераторов, чем vector
. deque
никогда не может быть реализовано вектором из-за его алгоритмической сложности и гарантий недействительности итераторов.
Сколько накладных расходов памяти связано? Ну, честно говоря, это немного бесполезный вопрос. Контейнеры STL спроектированы так, чтобы быть эффективными, и если бы вы копировали их функциональные возможности, вы либо получили бы что-то, что работает хуже, либо снова в том же месте. Зная их базовые структуры данных, вы можете узнать, какие накладные расходы памяти они используют, дают или отбирают, и это будет только больше, чем по уважительной причине, такой как оптимизация небольших строк.
deque
всегда было реализовано в STL с вектором.