青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

MyMSDN

MyMSDN記錄開發(fā)新知道

[轉(zhuǎn)]從C++的Return Value Optimization (RVO)到C#的value type

先看一段簡單的C++代碼:

Type get(int I){
    return Type(i);
} 

Type t = get(1); 

這里, 我們從C++的基本語義看上去, 應(yīng)該是Type(i) 調(diào)用一次拷貝構(gòu)造函數(shù), 在堆棧中生成一個臨時對象;然后,用該對象構(gòu)造返回對象;然后對這個臨時對象調(diào)用析構(gòu)函數(shù);在調(diào)用者方, 用返回的臨時對象調(diào)用拷貝構(gòu)造函數(shù)以初始化對象t, 返回對象的析構(gòu)函數(shù)在這之后, 函數(shù)返回之前調(diào)用。

所以, Type t = get(i); 應(yīng)該有三個拷貝構(gòu)造函數(shù)和兩個析構(gòu)函數(shù)的調(diào)用.

可是, 還有一種說法是, 編譯器可能會對這兩個臨時對象進(jìn)行優(yōu)化,最終的優(yōu)化結(jié)果會是只有一次的構(gòu)造函數(shù)。因為很明顯地可以看到, 這里我們其實只是要用一個整數(shù)構(gòu)造一個Type對象。

嗯. 似乎很有道理!

那么, 哪一種說法對呢? 沒有調(diào)查就沒有發(fā)言權(quán),于是本人用VC++6.0做了實驗。 放了些cout<<…..在拷貝構(gòu)造函數(shù)里,觀察打印的結(jié)果, 結(jié)果卻是跟我的simple, na?ve的預(yù)測一致。三個拷貝構(gòu)造函數(shù), 兩個析構(gòu)函數(shù)。

“你個弱智編譯器!腦袋進(jìn)水了吧?”(忘了編譯器沒腦袋了)“很明顯在這個例子里我的兩個臨時對象都沒有用的啊!”

于是,上網(wǎng), 查資料, google一下吧!

下面是我查到的一些結(jié)果:

其實, 這種對值傳遞的優(yōu)化的研究, 并不只局限于返回值。對下面這個例子:

void f(T t) { } 
void main(void){ 
    T t1;
    f(t1); 
} 

也有這種考慮。

f(T)是按值傳遞的。語義上應(yīng)該做一個復(fù)制, 使得函數(shù)內(nèi)部對T的改變不會影響到原來的t1.

但是,因為在調(diào)用f(t1)之后, 我們沒有再使用t1(除了一個隱含的destructor調(diào)用),是否可能把復(fù)制優(yōu)化掉, 直接使用t1呢?這樣可以節(jié)省掉一個拷貝構(gòu)造函數(shù)和一個析構(gòu)函數(shù)。

可是, 不論是對返回值的優(yōu)化, 還是對上面這種局部對象的優(yōu)化,在1995年的C++新標(biāo)準(zhǔn)草案出臺前都是為標(biāo)準(zhǔn)所嚴(yán)格限制的 (雖然有些編譯器并沒有遵行這個標(biāo)準(zhǔn), 還是支持了這種“優(yōu)化”)

那么, 這又是為什么呢?

這里面涉及到一個普遍的對side-effect的擔(dān)憂。

什么又是side-effect呢?

所謂side-effect就是一個函數(shù)的調(diào)用與否能夠?qū)ο到y(tǒng)的狀態(tài)造成區(qū)別。

int add(int i, int j){ return i+j; }就是沒有side-effect的,而

void set(int* p, int I, int v){ p[I]=v; }就是有side-effect的。因為它改變了一個數(shù)組元素的值, 而這個數(shù)組元素在函數(shù)外是可見的。

通常意義上來說, 所有的優(yōu)化應(yīng)該在不影響程序的可觀察行為的基礎(chǔ)上進(jìn)行的。否則,快則快了, 結(jié)果卻和所想要的完全不同!

而C++的拷貝構(gòu)造函數(shù)和析構(gòu)函數(shù)又很多都是有side-effect的。如果我們的“優(yōu)化”去掉了一個有side-effect的拷貝構(gòu)造函數(shù)和一個析構(gòu)函數(shù), 這個“優(yōu)化”就有可能改變程序的可觀察行為。(注意, 我這里說的是“可能”,因為“負(fù)負(fù)得正”, 兩個有side-effect的函數(shù)的調(diào)用, 在不考慮并行運(yùn)行的情況下, 也許反而不會影響程序的可觀察行為。不過, 這種塞翁失馬的事兒, 編譯器就很難判斷了)

基于這種憂慮, 1995年以前的標(biāo)準(zhǔn), 明確禁止對含有side-effect的拷貝構(gòu)造函數(shù)和析構(gòu)函數(shù)的優(yōu)化。同時, 還有一些對C++擴(kuò)充的提議, 考慮讓程序員自己對類進(jìn)行允許優(yōu)化的聲明。 程序員可以明確地告訴編譯器:不錯, 我這個拷貝構(gòu)造函數(shù), 析構(gòu)函數(shù)是有side-effect, 但你別管, 盡管優(yōu)化, 出了事有我呢!

哎, side-effect真是一個讓人又恨又愛的東西!它使編譯器的優(yōu)化變得困難;加大了程序維護(hù)和調(diào)試的難度。因此 functional language 把side-effect當(dāng)作洪水猛獸一樣,干脆禁止。但同時,我們又很難離開side-effect. 不說程序員們更習(xí)慣于imperative 的編程方法, 象數(shù)據(jù)庫操作,IO操作都天然就是side-effect.

不過,個人還是認(rèn)為C++標(biāo)準(zhǔn)對“優(yōu)化”的保守態(tài)度是有道理的。無論如何,讓“優(yōu)化”可以潛在地偷偷地改變程序的行為總是讓人想起來就不舒服的。

但是, 矛盾是對立統(tǒng)一的。(想當(dāng)年俺馬列可得了八十多分呢)。 對這種aggressive的“優(yōu)化”的呼聲是一浪高過一浪。 以Stan Lippeman為首的一小撮頑固分子對標(biāo)準(zhǔn)的顛覆和和平演變的陰謀從來就沒有停止過。 這不?在1996年的一個風(fēng)雨交加的夜晚, 一個陰險的C++新標(biāo)準(zhǔn)草案出爐了。在這個草案里, 加入了一個名為RVO (Return Value Optimization) 的放寬對優(yōu)化的限制, 妄圖走資本主義道路, 給資本家張目的提案。其具體內(nèi)容就是說:允許編譯器對命名過的局部對象的返回進(jìn)行優(yōu)化, 即使拷貝構(gòu)造函數(shù)/析構(gòu)函數(shù)有side-effect也在所不惜。這個提議背后所隱藏的思想就是:為了提高效率, 寧可冒改變程序行為的風(fēng)險。寧要資本主義的苗, 不要社會主義的草了!

我想, 這樣的一個罪大惡極的提案竟會被提交,應(yīng)該是因為C++的值拷貝的語義的效率實在太“媽媽的”了。 當(dāng)你寫一個 Complex operator+(const Complex& c1, const Complex& c2);的時候, 竟需要調(diào)用好幾次拷貝構(gòu)造函數(shù)和析構(gòu)函數(shù)!同志們!(沉痛地, 語重心長地)社會主義的生產(chǎn)關(guān)系的優(yōu)越性怎么體現(xiàn)啊?

接下來, 當(dāng)我想Google C++最新的標(biāo)準(zhǔn), 看RVO是否被最終采納時, 卻什么也找不到了。 到ANSI的網(wǎng)站上去, 居然要付錢才能DOWNLOAD文檔。 “老子在城里下館子都不付錢, down你幾個爛文檔還要給錢?!”

故事沒有結(jié)局, 實在是不爽。 也不知是不是因為標(biāo)準(zhǔn)還沒有敲定, 所以VC++6 就沒有優(yōu)化, 還是VC根本就沒完全遵守標(biāo)準(zhǔn)。

不過,有一點是肯定的。 當(dāng)寫程序的時候, 最好不要依賴于RVO (有人, 象Stan Lippeman, 又叫它NRV優(yōu)化)。 因為, 不論對標(biāo)準(zhǔn)的爭論是否已經(jīng)有了結(jié)果, 實際上各個編譯器的實現(xiàn)仍還是各自為政, 沒有統(tǒng)一。 一個叫SCOtt Meyers的家伙(忘了是賣什么的了)就說, 如果你的程序依賴于RVO, 最好去掉這種依賴。也就是說, 不管RVO到底標(biāo)準(zhǔn)不標(biāo)準(zhǔn), 你還是不能用。 不僅不能用, 還得時刻警惕著RVO可能帶來的程序行為上的變化。 (也不知這幫家伙瞎忙了半天到底為啥!)

說到這里, 倒想起了C#里一個困惑了我很久的問題。記得讀C#的specification的時候, 非常不解為什么C#不允許給value type 定義析構(gòu)函數(shù)。

這里, 先簡略介紹一下C#里的value type (原始數(shù)據(jù)類型, struct 類型)。

在C#里的value_type就象是值, 永遠(yuǎn)只能copy, 取值。因此, 它永遠(yuǎn)是in-place的。如果你把一個value type的數(shù)據(jù)放在一個對象里,它的生命期就和那個對象相同;如果你聲明一個value type 的變量在函數(shù)中, 它的生命期就在lexical scope里。

{

  The_ValueType value;

}//value 到這里就死菜了

啊呀呀! 這不正是我們懷念的C++的stack object嗎?

在C++里,Auto_ptr, shared_ptr, 容器們, 不都是利用析構(gòu)函數(shù)來管理資源的嗎?

C#,Java 雖然利用garbage collection技術(shù)來收集無用對象, 使我們不用再擔(dān)心內(nèi)存的回收。 但garbage collection并不保證無用對象一定被收集, 并不保證Dispose()函數(shù)一定被調(diào)用, 更不保證一個對象什么時候被回收。 所以對一些非內(nèi)存的資源, 象數(shù)據(jù)庫連接, 網(wǎng)絡(luò)連接, 我們還是希望能有一個類似于smart pointer的東西來幫我們管理啊。(try-finally 雖然可以用, 但因為它影響到lexical scope, 有時用起來不那么方便)

于是, 我對C#的取消value type的析構(gòu)函數(shù)充滿了深厚的階級仇恨。

不過, 現(xiàn)在想來, C#的這種設(shè)計一定是懲于C++失敗的教訓(xùn):

   1. value type 沒有拷貝構(gòu)造函數(shù)。C#只做缺省copy, 沒有side-effect
   2. value type 不準(zhǔn)有析構(gòu)函數(shù)。C#有g(shù)arbage collection, 析構(gòu)函數(shù)的唯一用途只會是做一些side-effect象關(guān)閉數(shù)據(jù)庫連接。 所以取消了析構(gòu)函數(shù), 就取消了value type的side-effect.
   3. 沒有了side-effect, 系統(tǒng)可以任意地做優(yōu)化了

對以下程序:

The_Valuetype get(int I){return The_Valuetype(i);}

The_Valuetype t = get(1);

在C#里我們可以快樂地說:只調(diào)用了一次構(gòu)造函數(shù)。 再沒有side-effect的沙漠, 再沒有難以優(yōu)化的荒原, smart pointer望而卻步, 效率之花處處開遍。 I have a dream, ……

轉(zhuǎn)載自:http://gugu99.itpub.net/post/34143/466008

posted on 2010-04-06 19:42 volnet 閱讀(598) 評論(0)  編輯 收藏 引用 所屬分類: 知識庫(KnowledgeLibrary)C/C++

特殊功能
 
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久一区国产| 欧美国产成人精品| 精品不卡一区| 国产一级揄自揄精品视频| 国产一区在线播放| 在线观看日韩av电影| 亚洲国产天堂久久综合| 一本久道久久久| 亚洲一区影音先锋| 久久偷看各类wc女厕嘘嘘偷窃| 久久久一区二区| 亚洲国产午夜| 亚洲视频观看| 久久久久久9| 欧美日韩一区成人| 国产一区亚洲| 一区二区三区日韩精品视频| 欧美在线综合| 亚洲国产精品专区久久| 亚洲一区二区免费| 欧美成人精品在线视频| 国产老女人精品毛片久久| 亚洲人成小说网站色在线| 午夜精品福利一区二区蜜股av| 免费成人高清视频| 亚洲色图在线视频| 欧美高清视频在线播放| 国产欧美日韩另类一区| 日韩视频免费观看| 另类专区欧美制服同性| 亚洲婷婷在线| 国产精品都在这里| 欧美激情日韩| 国产一区在线看| 亚洲新中文字幕| 亚洲国产精品va在线观看黑人| 午夜欧美大片免费观看| 欧美日韩中文字幕在线视频| 在线观看视频一区二区| 欧美在线观看视频一区二区| 亚洲国产欧美一区二区三区丁香婷| 亚洲欧美日韩久久精品| 欧美日韩在线播放一区二区| 亚洲激情视频网站| 久久综合色综合88| 欧美一级黄色网| 国产精品五月天| 亚洲欧美区自拍先锋| 韩国福利一区| 亚洲综合色在线| 一区二区三区国产精品| 欧美日韩国产美| 一级成人国产| 99精品国产高清一区二区| 欧美日韩hd| 一区二区免费在线观看| 亚洲人成网在线播放| 欧美黑人在线观看| 一区二区日韩免费看| 亚洲精品美女久久7777777| 欧美精品成人| 一区二区电影免费观看| av成人手机在线| 国产精品豆花视频| 欧美一区二区三区电影在线观看| 亚洲影院高清在线| 国产一区二区三区久久久久久久久| 久久国内精品自在自线400部| 欧美亚洲一区二区在线观看| 国产一区二区三区在线观看视频| 久久久久国产精品厨房| 久久先锋资源| 亚洲另类自拍| 一区二区三区欧美成人| 国产欧美综合一区二区三区| 久久久久久久精| 美女脱光内衣内裤视频久久网站| 亚洲精品四区| 亚洲新中文字幕| 狠狠色综合网站久久久久久久| 欧美韩日一区| 国产精品色一区二区三区| 久久三级福利| 欧美日韩国产小视频在线观看| 亚洲欧美日韩一区二区| 久久精品日韩一区二区三区| 日韩一区二区精品视频| 亚洲欧美视频在线观看视频| 亚洲国产高清一区| 亚洲无人区一区| 亚洲成色最大综合在线| 99视频在线精品国自产拍免费观看 | 亚洲视频观看| 狠狠爱综合网| 91久久夜色精品国产网站| 国产精品乱码一区二区三区| 老牛嫩草一区二区三区日本| 欧美日韩一区二区三区四区在线观看 | 国产欧美日韩一区| 黄色成人av在线| 亚洲国产精品传媒在线观看 | 在线性视频日韩欧美| 欧美在线视频免费| 一本色道久久加勒比88综合| 欧美综合国产| 午夜久久福利| 欧美日韩国产专区| 欧美成人精品在线视频| 国产麻豆午夜三级精品| 日韩亚洲国产欧美| 亚洲高清av在线| 欧美在线视频免费观看| 亚洲欧美在线一区二区| 欧美日韩亚洲国产一区| 亚洲国产黄色片| 激情久久久久久| 亚洲欧美综合网| 亚洲一区一卡| 欧美日韩一区视频| 最新高清无码专区| 亚洲国产欧美一区二区三区同亚洲| 一区二区日韩| 亚洲视频综合在线| 欧美日韩一区二区免费在线观看| 亚洲国产成人久久综合| 91久久综合亚洲鲁鲁五月天| 久久综合999| 免费亚洲电影在线| 在线日本成人| 麻豆91精品| 欧美高清视频一区| 亚洲黑丝在线| 欧美成人亚洲成人| 亚洲电影免费| 亚洲精选视频免费看| 欧美激情一区二区久久久| 亚洲欧洲视频在线| 一区二区三区欧美成人| 欧美视频一区在线| 亚洲无玛一区| 久久久精品国产免费观看同学 | 亚洲一区亚洲二区| 国产精品美女久久久| 亚洲欧美日韩电影| 久久天堂精品| 新片速递亚洲合集欧美合集| 国产精品一二三| 亚洲一级片在线看| 久久久91精品国产一区二区精品| 国产亚洲一区二区三区| 久久在线免费观看视频| 亚洲区一区二| 亚洲欧美视频一区| 好吊色欧美一区二区三区四区 | 久久久久久久久久久一区| 国色天香一区二区| 免费看av成人| 一区二区三区回区在观看免费视频| 午夜性色一区二区三区免费视频| 国产日韩欧美二区| 牛人盗摄一区二区三区视频| 日韩一区二区精品视频| 久久激情网站| 久久超碰97人人做人人爱| 美国成人直播| 亚洲视频福利| 揄拍成人国产精品视频| 欧美午夜欧美| 久久精品中文| 99精品视频免费全部在线| 久久久久中文| 亚洲尤物在线视频观看| 亚洲高清不卡| 国产麻豆精品视频| 欧美日本乱大交xxxxx| 午夜精品久久久久久久久| 亚洲国产精品国自产拍av秋霞 | 一区二区国产在线观看| 国内揄拍国内精品少妇国语| 欧美精品在线播放| 久久成人人人人精品欧| 亚洲最新视频在线播放| 欧美不卡一卡二卡免费版| 欧美一级片一区| 一本色道久久综合亚洲91| 在线免费观看一区二区三区| 国产精品久久久久久久久免费| 麻豆精品在线播放| 欧美一级专区| 亚洲一区欧美激情| 一本一本久久a久久精品综合麻豆| 浪潮色综合久久天堂| 欧美一区深夜视频| 亚洲一区在线观看免费观看电影高清| 亚洲国产高清在线| 亚洲成人资源| 亚洲国产精品va| 在线欧美三区| 亚洲福利在线看| 亚洲丰满少妇videoshd|