c++的std::string的讀時也拷貝技術!
嘿嘿,你沒有看錯,我也沒有寫錯,是讀時也拷貝技術。什麼?我的錯,你之前聽說寫過時才拷貝,嗯,不錯的確有這門技術,英文是copy on write,簡寫就是cow,非常』牛』!那麼我們就來看看這個』牛』技術的效果吧。
我們先編寫一段程式
01.
#include
02.
#include
03.
#include
04.
05.
static
long
getcurrenttick()
06.
13.
14.
int
main( )
15.
21.
fprintf
(stdout,
"耗時[%d] /n"
,getcurrenttick() - begin );
22.
}
嗯,乙個非常大的字串,有10m位元組的x,並且執行了100此拷貝。編譯執行它,非常快,在我的虛擬機器甚至不要1個毫秒。
現在我們來對這個string加點料!
01.
int
main(
void
)
08.
fprintf
(stdout,
"耗時[%d] /n"
,getcurrenttick() - begin );
09.
}
現在我們再編譯並執行這斷程式,居然需要4~5秒!哇!非常美妙的寫時才拷貝技術,效能和功能的完美統一。
我們再來看看另外一種情況!
1.
string original =
"hello"
;
2.
char
& ref = original[0];
3.
string clone = original;
4.
ref =
'y'
;
我們生成了乙個string,並保留了它首字元的引用,然後複製這個string,修改string中的首字元。因為寫操作只是直接的修改了記憶體中的指定位置,這個string就根本不能感知到有寫發生,如果寫時才拷貝是不成熟的,那麼我們將同時會修改original和clone兩個string。那豈不是災難性的結果?幸好上述問題不會發生。clone的值肯定是沒有被修改的。看來cow就是非常的牛!
以上都證明了我們的cow技術非常牛!
有太陽就有黑暗,這句說是不是有點耳熟?
01.
int
main(
void
)
08.
fprintf
(stdout,
"耗時[%d] /n"
,getcurrenttick() - begin );
09.
}
啊,居然也是4~5秒!你可能在想,我只是做了乙個讀,沒有寫嘛,這到底是怎麼回事?難道還有讀時也拷貝的技術!。
不錯,為了避免了你通過操作符獲取string內部指標而直接修改字串的內容,在你使用了the_base[0]後,這個字串的寫時才拷貝技術就失效了。
c++標準的確就是這樣的,c++標準認為,當你通過迭代器或獲取到string的內部位址的時候,string並不知道你將是要讀還是要寫。這是它無法確定,為此,當你獲取到內部引用後,為了避免不能捕獲你的寫操作,它在此時廢止了寫時才拷貝技術!
這樣看來我們在使用cow的時候,一定要注意,如果你不需要對string的內部進行修改,那你就千萬不要使用通過操作符和迭代器去獲取字串的內部位址引用,如果你一定要這麼做,那麼你就必須要付出代價。當然,string還提供了一些使迭代器和引用失效的方法。比如說push_back,等, 你在使用之後再使用迭代器之後,引用就有可能失效了。那麼你又回到了cow的世界!比如下面的乙個例子
01.
int
main( )
02.
12.
fprintf
(stdout,
"耗時[%d] /n"
,getcurrenttick() - begin );
13.
}
一切又恢復了正常!如果對返回引用進行了操作又會發生情況呢,有興趣的朋友可以試試!結果非常令人驚訝。
另外:上述例子是在linux環境下編譯的,使用stl是gnu的stl。windows上我用的是vs2003,但是非常明顯vs2003一點都不支援cow。
這篇文章出自
這裡,我使用了它的例子。但是我重新自己組織了內容。
編寫這篇文章的同時,我還參考了耗子的《標準c++類string的copy-on-write技術》
一文
也讀名人部落格
也讀名人部落格 比較兩位姐姐之部落格,我更傾向於前者。洪晃,陳凱歌之前妻,一位精練的才女,是 樂 雜質的創辦者。其部落格內容豐富多彩,讓人回味無窮,讀其部落格,如見良師益友,受益非淺。老徐,即徐靜蕾,是 第二眼美女 的代表,乙個電影藝人,也是導演群中的後起之秀。不可否認,她也是一位才女,但其部落格記...
CString比較時要注意的
最近上班的時候接到乙個需求 1 使用者給定了乙個列表,裡面是一些中英文混雜的字串,標點符號也是混的 比如 序號 名稱 1 1號和a去圖書館 有英文數字 中文 英文小寫 2 和同學b聚會定在 日 有全形數字 中文 英文小寫 3 c的書名是 數學 有中文標點符號 中文 英文大寫 4 jack 是他的名字...
c String類的寫時拷貝
在學習寫時拷貝前,我們先看乙個例子 class string string private char mptr int main 這段 中僅實現了建構函式和析構函式,在構造str1和str2時都開闢了新的記憶體空間,但對於str2,僅是單純的使用了它,並沒有對這塊空間進行操作,所以在這裡給str2重...