(Отказ от ответственности: я не знаю, что может сказать об этом стандарт С++. Я знаю, я ужасен)
во время работы на очень больших строках я заметил, что 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 используют copy-on-read (?).
#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 секунды для всей игрушечной программы. Я не на 100% комфортно с этим. Строки STL действительно копируются на чтение, или они позволяют копировать на запись вообще? Я убежден, что оператор [] имеет некоторые гарантии против того, кто сохранит ссылку, которую он вернет, а затем напишет на нее; это действительно так? Если нет, что на самом деле происходит? Если кто-то может указать на какой-то соответствующий раздел в стандарте С++, это также будет оценено.
Для справки, я использую g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3
и GNU STL.