(免責事項:C ++標準がこれについて何を言っているのかわかりません..私は恐ろしいです)
非常に大きな文字列を操作しているときに、std::stringがコピーオンライトを使用していることに気付きました。観察された動作を再現する最小のループを作成することができました。たとえば、次のループは疑わしいほど高速に実行されます。
#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!
}
}
しばらくの間、発見を楽しんだ後、ベース文字列からの読み取り(operator []を使用)も、おもちゃのプログラム全体で0.3秒かかることがわかりました。これには100%満足していません。STL文字列は実際にコピーオンライトですか、それともコピーオンライトを許可していますか?私は、operator []が、それが返す参照を保持し、後でそれに書き込む人に対して、いくつかの安全策を持っていると思うようになりました。これは本当に本当ですか?そうでない場合、実際に何が起こっているのでしょうか。誰かがC++標準の関連するセクションを指すことができれば、それもありがたいです。
参考までに、とGNUSTLを使用g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3
しています。