(Tuyên bố từ chối trách nhiệm: Tôi không biết tiêu chuẩn C++ có thể nói gì về điều này..Tôi biết, tôi thật kinh khủng)Chuỗi STL GNU: là sao chép trên ghi có liên quan ở đây không?
khi hoạt động trên các chuỗi rất lớn Tôi nhận thấy rằng std :: string đang sử dụng sao chép -Viết. Tôi quản lý để viết vòng lặp nhỏ nhất mà sẽ tái tạo các hành vi quan sát và một sau, ví dụ, chạy nghi ngờ nhanh:
#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;
}
}
khi thêm một ghi trong cơ thể lặp a_copy[1] = 'B';
, một bản sao thực tế dường như đã diễn ra, và chương trình chạy trong 0,3 giây thay vì một vài phần nghìn giây. 100 bài viết đã làm chậm nó xuống khoảng 100 lần.
Nhưng sau đó nó trở nên kỳ lạ. Một số chuỗi của tôi không được viết, chỉ đọc từ, và điều này đã không được phản ánh trong thời gian thực hiện, đó là gần như chính xác tỷ lệ thuận với số lượng hoạt động trên các chuỗi. Với một số đào, tôi thấy rằng chỉ cần đọc từ một chuỗi vẫn cho tôi rằng hiệu suất hit, do đó, nó đã dẫn tôi giả sử các chuỗi GNU STL đang sử dụng 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!
}
}
Sau reveling trong khám phá của tôi trong một thời gian, tôi phát hiện ra rằng đọc (với nhà điều hành []) từ chuỗi cơ sở cũng mất 0.3s cho toàn bộ program..I'm đồ chơi không phải là 100% cảm thấy thoải mái với điều này. Các chuỗi STL thực sự là sao chép trên máy đọc hay chúng có cho phép copy-on-write không? Tôi đã nghĩ rằng toán tử [] có một số biện pháp bảo vệ chống lại một người sẽ giữ tham chiếu nó trả về và sau đó viết cho nó; Đây đúng là tình trạng đó phải không? Nếu không, điều gì đang thực sự xảy ra? Nếu ai đó có thể trỏ đến một số phần có liên quan trong tiêu chuẩn C++, điều đó cũng sẽ được đánh giá cao.
Để tham khảo, tôi đang sử dụng g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3
và GNU STL.
Vì câu trả lời dưới đây cho thấy đây có lẽ là câu hỏi về trình biên dịch nhiều hơn câu hỏi chuẩn C++. Bạn đang sử dụng trình biên dịch nào? Bạn đã thử các cài đặt tối ưu hóa khác nhau chưa? –
Hơn so với trình biên dịch tôi tưởng tượng rằng điều này đã làm với việc thực hiện STL cụ thể mà OP đang sử dụng. Từ góc nhìn tiêu chuẩn, tôi nghĩ Charles Bailey đã trả lời. – Raj
C++ 98/03 được thiết kế để cho phép các chuỗi COW, nhưng COW không bắt buộc. Ngẫu nhiên, std :: string không phải là một phần của STL mặc dù các khái niệm STL sau đó được áp dụng cho nó. –