(Отказ от ответственности: я не знаю, что стандарт C ++ может сказать по этому поводу ... Я знаю, я ужасен)
при работе с очень большими строками я заметил, что std :: string использует copy-on-write. Мне удалось написать наименьший цикл, который бы воспроизводил наблюдаемое поведение, а следующий, например, работает подозрительно быстро:
#include <string>
using std::string;
int main(void) {
string basestr(1024 * 1024 * 10, 'A');
for (int i = 0; i < 100; i++) {
string a_copy = basestr;
}
}
при добавлении записи в тело цикла a_copy[1] = 'B';
фактическая копия, очевидно, имела место, и программа работала в течение 0,3 с вместо нескольких миллисекунд. 100 записей замедлили его примерно в 100 раз.
Но потом стало странно. Некоторые из моих строк не были записаны, только прочитаны, и это не отразилось на времени выполнения, которое было почти точно пропорционально количеству операций над строками. Немного покопавшись, я обнаружил, что простое чтение из строки все еще дает мне снижение производительности, поэтому я предположил, что строки GNU STL используют функцию копирования при чтении (?).
#include <string>
using std::string;
int main(void) {
string basestr(1024 * 1024 * 10, 'A');
for (int i = 0; i < 100; i++) {
string a_copy = basestr;
a_copy[99]; // this also ran in 0.3s!
}
}
Поработав некоторое время над своим открытием, я обнаружил, что чтение (с оператором []) из базовой строки также занимает 0,3 с для всей игрушечной программы. Действительно ли строки STL копируются при чтении или они вообще допускают копирование при записи? Я склонен думать, что оператор [] имеет некоторые гарантии против того, кто будет хранить ссылку, которую он возвращает, и позже будет писать в нее; это действительно так? Если нет, то что на самом деле происходит? Если кто-то может указать на какой-то соответствующий раздел в стандарте C ++, это также будет оценено.
Для справки я использую g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3
и GNU STL.