C語(yǔ)言高效得簡(jiǎn)直不合理
【譯者序:我翻譯此文并非推崇C而貶低其他語(yǔ)言。我翻譯此文,只是因?yàn)樽髡叩亩嗵幘降囊?jiàn)解讓人深思。作者的出發(fā)點(diǎn),很明顯,是純技術(shù)的;各位讀者且謹(jǐn)記這一點(diǎn)?!?/p>
多年來(lái),我一直試圖擺脫C語(yǔ)言。太簡(jiǎn)單,太多細(xì)節(jié)需要處理,太古老,太低級(jí)。我一直鐘愛(ài)Java,C++,Erlang。我用它們創(chuàng)建了很多項(xiàng)目,并且自己為這些項(xiàng)目感到驕傲;然而,這些語(yǔ)言,最終,都傷了我的心。他們做出承諾,卻無(wú)法兌現(xiàn);他們專(zhuān)注于錯(cuò)誤的東西,并且所做的“折衷”最終讓你倍感煎熬。于是,我不得不求助于C。
C就是一個(gè)萬(wàn)能背包。它高效且高產(chǎn),有強(qiáng)大的工具和廣泛的社區(qū)支持,并且它對(duì)它所做的“折衷”非常誠(chéng)實(shí)。
對(duì)于其他語(yǔ)言,他們能讓你更快的工作,但從長(zhǎng)遠(yuǎn)來(lái)看,當(dāng)性能和可靠性變得重要時(shí),C將會(huì)為你省去不少麻煩事兒。我個(gè)人再次非常痛苦的學(xué)到了這一刻。
簡(jiǎn)單直觀
C語(yǔ)言是非常棒的高級(jí)語(yǔ)言。我重復(fù)一遍,C語(yǔ)言是非常棒的高級(jí)語(yǔ)言。當(dāng)然,它沒(méi)有Java、C#等高級(jí),自然也沒(méi)有Erlang、Python或者 Javascript高級(jí)。但是,他和C++在語(yǔ)言的高級(jí)程度上,是一樣的;而然它比C++更加簡(jiǎn)單。當(dāng)然C++提供了更多的抽象,然而它并沒(méi)有給出比C 更高級(jí)的抽象。在使用C++時(shí),你考慮的細(xì)節(jié)并不比你使用C時(shí)的少,除此之外,你還要考慮一堆可笑的無(wú)意義東西。
"When someone says: 'I want a programming language in which I need only say what I wish done', give him a lollipop." - Alan J. Perlis 當(dāng)有人說(shuō):“我想要一種編程語(yǔ)言,我僅需要對(duì)它說(shuō)我想干啥就行了。”那么給那個(gè)小屁孩兒一個(gè)棒棒糖吧。 Alan J. Perlis |
我們想要找一種低級(jí)語(yǔ)言來(lái)代替C,然而找不到;這并非是因?yàn)镃語(yǔ)言是低級(jí)語(yǔ)言,相反,恰恰是因?yàn)镃語(yǔ)言作為底層機(jī)器上的高層抽象太成功了。它如此成功,以至于讓大多數(shù)的低級(jí)語(yǔ)言顯得毫無(wú)意義。C就是這么擅長(zhǎng)它所做的。
C語(yǔ)言的語(yǔ)法和語(yǔ)義強(qiáng)大而直觀。它可以用以編寫(xiě)高級(jí)算法,同時(shí)也可以用以處理底層硬件邏輯。正因?yàn)槠鋸?qiáng)大、簡(jiǎn)單和直觀的語(yǔ)法和語(yǔ)義,C語(yǔ)言并不會(huì)給我們一些額外的認(rèn)知上的負(fù)擔(dān),從而讓編程者專(zhuān)注于真正重要的事情。
C顛覆了我們對(duì)低級(jí)語(yǔ)言的認(rèn)識(shí)。這真了不起。
簡(jiǎn)單的代碼,精致的類(lèi)型
c語(yǔ)言是一種弱類(lèi)型語(yǔ)言,其類(lèi)型系統(tǒng)非常簡(jiǎn)單。和C++還有java明顯的一個(gè)區(qū)別是,c里面你不能定義“類(lèi)”(class),你不可以把所有的運(yùn)行時(shí)需要的東西都放到“類(lèi)”里面。你的所有工作都嚴(yán)格基于結(jié)構(gòu)(struct)和聯(lián)合(union)。所有的函數(shù)調(diào)用者必須明確被調(diào)用函數(shù)的參數(shù)類(lèi)型和返回值類(lèi)型。所以調(diào)用者的自由相對(duì)有限。
你只是想要個(gè)香蕉,結(jié)果來(lái)了只自稱(chēng)森林之王的大猩猩——Joe Armstrong
你剛剛聽(tīng)起來(lái)像是c語(yǔ)言缺點(diǎn)的東西某種程度上確實(shí)一種優(yōu)點(diǎn):c語(yǔ)言的API面對(duì)用戶都力圖精簡(jiǎn)。這避免了龐雜的框架,而力圖在簡(jiǎn)單的類(lèi)型基礎(chǔ)上創(chuàng)造一個(gè)小巧的函數(shù)庫(kù)。
而面向?qū)ο蟮恼Z(yǔ)言往往在復(fù)雜的類(lèi)型基礎(chǔ)上又構(gòu)造了龐雜的基礎(chǔ)類(lèi)庫(kù),這些庫(kù)提供了大量的相互依賴(lài)的接口,他們的參數(shù)和返回值的“類(lèi)”型也因此更加復(fù)雜。每一種“類(lèi)”又定義了大量的復(fù)雜的方法和屬性……好吧,更加復(fù)雜了。
這并不是說(shuō)吐面向?qū)ο缶拖M儚?fù)雜,但是他們貌似鼓勵(lì)你把事情變復(fù)雜。他們的復(fù)雜性使你很容易犯錯(cuò)誤。相對(duì)來(lái)說(shuō),c就很少導(dǎo)致錯(cuò)誤。c語(yǔ)言盡力構(gòu)建一個(gè)簡(jiǎn)潔、通俗的類(lèi)型系統(tǒng),使用它你會(huì)發(fā)現(xiàn)你不需要顧及那么多的依賴(lài)關(guān)系。這使你的開(kāi)發(fā)變得更加簡(jiǎn)單。
速度之王
c語(yǔ)言不論在處理器中還是在內(nèi)存堆棧里,都是速度最快的。而且其高效不僅僅體現(xiàn)在速度上,即使是內(nèi)存的管理以及啟動(dòng)時(shí)間上,也無(wú)人望其項(xiàng)背。當(dāng)你需要平衡空間和時(shí)間的消費(fèi)時(shí),c語(yǔ)言從來(lái)不會(huì)對(duì)你隱藏任何細(xì)節(jié),原因如下:
-強(qiáng)大的編譯器 -k&p風(fēng)格 |
每次那些更高層次的編程語(yǔ)言(比如java或者h(yuǎn)askell),聲稱(chēng)自己能產(chǎn)生接近c(diǎn)語(yǔ)言的表現(xiàn)從程序的時(shí)候,這在我聽(tīng)來(lái)簡(jiǎn)直就是笑話。通常,他們?yōu)榱藢?shí)現(xiàn)這一點(diǎn),不得不在語(yǔ)法上做出一些稀奇古怪的事情,比如專(zhuān)門(mén)搞一些“聰明的”編譯器或者虛擬機(jī)……這種古怪的優(yōu)化行為使語(yǔ)言失去了原本簡(jiǎn)單的性質(zhì),更何況這種優(yōu)化往往只是針對(duì)處理器
當(dāng)你想要用c語(yǔ)言寫(xiě)一些對(duì)運(yùn)行速度要求嚴(yán)格的東西時(shí),你可以很清楚的知道為什么他很快,這一點(diǎn)不因?yàn)槟闶褂玫木幾g器或者虛擬機(jī)不同而改變。應(yīng)用程序中,GC(垃圾回收)的設(shè)置將會(huì)影響運(yùn)行。而人機(jī)交互將會(huì)影響垃圾回收對(duì)于數(shù)據(jù)的處理。
c語(yǔ)言的代碼優(yōu)化直接而有效。即使你不這樣認(rèn)為,在實(shí)際工作中也有大量的工具幫助你了解其中的緣故。相對(duì)來(lái)說(shuō),你根本沒(méi)有必要為此壯起膽子去嘗試學(xué)習(xí)什么虛擬機(jī),什么“智能優(yōu)化編譯器”。當(dāng)你在使用cpu,內(nèi)存和IO分析器的時(shí)候,c語(yǔ)言絕對(duì)不會(huì)讓你對(duì)底層到底發(fā)生了什么感到困惑。以上所言,不論是從處理器的角度還是從內(nèi)存堆棧角度,都證明了c語(yǔ)言是速度之王。
更快的“編寫(xiě)-運(yùn)行-調(diào)試”周期
“編寫(xiě)-運(yùn)行-調(diào)試”這個(gè)開(kāi)發(fā)周期對(duì)于程序員是十分重要的。如果這個(gè)周期足夠快,開(kāi)發(fā)中的人機(jī)互動(dòng)足夠多,那么你的任務(wù)就進(jìn)行的足夠迅速。c具有主流靜態(tài)類(lèi)型語(yǔ)言中最快速的人機(jī)交互性能。
樂(lè)觀是程序員的職業(yè)病,返工是他們的唯一藥方 -Kent Beck |
因?yàn)?ldquo;編寫(xiě)-運(yùn)行-調(diào)試”周期更多的是一種開(kāi)發(fā)工具的使用原則而并不是一個(gè)語(yǔ)言的核心,所以他經(jīng)常被忽略。雖然如此,怎么宣揚(yáng)這個(gè)循環(huán)對(duì)于開(kāi)發(fā)速度的攻擊都不為過(guò)。悲催的是,這一循環(huán)已經(jīng)被很多變成語(yǔ)言遺忘了,他們反而去追求使用中的代碼的可讀性。所以,事實(shí)是,c仍然是最快的語(yǔ)言。
調(diào)試以及核心轉(zhuǎn)儲(chǔ)
對(duì)于任何你想將你的代碼移植過(guò)去的系統(tǒng),你幾乎都可以發(fā)現(xiàn)一些c語(yǔ)言調(diào)試工具和核心轉(zhuǎn)儲(chǔ)工具。他們對(duì)于你能夠快速找到源代碼中的問(wèn)題所在是非常重要的。當(dāng)然,他們也可能出現(xiàn)問(wèn)題。
Error, no keyboard -- press F1 to continue. |
對(duì)于其他的編程語(yǔ)言來(lái)說(shuō),就沒(méi)有這么多的工具了。不論如何你都得承認(rèn),這些工具對(duì)于你c語(yǔ)言的變成起了十分重要的作用。假如要你寫(xiě)一個(gè)c語(yǔ)言與其他語(yǔ)言的接口,或許你費(fèi)了九牛二虎之力,卻做出了一個(gè)結(jié)構(gòu)十分復(fù)雜,運(yùn)行十分脆弱,使用根本白瞎的廢物。
如果是純粹用c寫(xiě)的程序,你可以察看調(diào)用堆棧,變量,參數(shù),當(dāng)前線程……一切的內(nèi)存當(dāng)中最基礎(chǔ)的東西都毫發(fā)畢見(jiàn)。這真的很有效,尤其是當(dāng)你面對(duì)一個(gè)已經(jīng)宕機(jī)幾天的服務(wù)器進(jìn)程而無(wú)計(jì)可施。而當(dāng)你面對(duì)一個(gè)用其他高級(jí)語(yǔ)言寫(xiě)就的程序是……準(zhǔn)備受死吧……
從任何地方調(diào)用
C有一個(gè)標(biāo)準(zhǔn)化的應(yīng)用程序二進(jìn)制接口(ABI)支持每個(gè)操作系統(tǒng),語(yǔ)言和平臺(tái)的存在。它不需要運(yùn)行或其他固有的開(kāi)銷(xiāo)。這意味著你編寫(xiě)的代碼在C不僅是有價(jià)值的,從C代碼的調(diào)用方,但對(duì)于每一個(gè)可以想象的包,在語(yǔ)言和環(huán)境中還是存在。
"Portability is a result of few concepts and complete definition"
- J. Palme |
您可以使用獨(dú)立的可執(zhí)行文件,腳本語(yǔ)言,內(nèi)核代碼中,嵌入代碼的C代碼,作為一個(gè)DLL,甚至從SQL調(diào)用。這是用得上系統(tǒng)編程和可插拔庫(kù)。如果你想要寫(xiě)的東西一旦有可用的最可能的環(huán)境和使用情況,C是唯一明智的選擇。
是的!它有瑕疵
在C語(yǔ)言中有許多”瑕疵“ 。它沒(méi)有邊界檢查,很容易發(fā)生內(nèi)存沖突,有懸空指針和內(nèi)存/資源泄漏,螺栓支持并發(fā)性,沒(méi)有模塊,沒(méi)有命名空間。錯(cuò)誤處理可能相當(dāng)繁瑣和冗長(zhǎng)。當(dāng)調(diào)用堆棧崩潰,或者攻擊性輸入操縱你的進(jìn)程,很容易就產(chǎn)生一堆錯(cuò)誤。
"When all else fails, read the instructions." 當(dāng)其他辦法都失效時(shí),請(qǐng)查看說(shuō)明! - L. Lasellio |
它的瑕疵是非常非常有名的,這是一種優(yōu)點(diǎn)。所有的語(yǔ)言和實(shí)現(xiàn)有陷阱和難題。C只是更坦率的告訴它。還有大量的靜態(tài)和運(yùn)行時(shí)工具來(lái)幫你處理最常見(jiàn)的和危險(xiǎn)的錯(cuò)誤。世界上很多使用最廣泛和可靠的軟件是用C打造,這就是缺陷被夸大了的證據(jù),這些瑕疵容易檢測(cè)和修復(fù)。
為了編寫(xiě)couchbase,我們團(tuán)隊(duì)大概花了2 + 人/月解決Erlang虛擬機(jī)的問(wèn)題。我們?cè)贓rlang的編譯器上花費(fèi)了大量的時(shí)間和精力,卻仍然不確定到底發(fā)生了什么,而結(jié)論是或許是我們的插件的c 語(yǔ)言代碼出了什么問(wèn)題。我們想找出問(wèn)題,然而卻找不到。最終我們確定這是Erlang的核心里面有一個(gè)條件矛盾錯(cuò)誤。這是我們唯一的成果。而太多的語(yǔ)言抽象掉了太多的東西,這無(wú)疑增加了類(lèi)似我們遇到的困難。
最初,出于性能原因,我們決定用c重寫(xiě)couchbase的代碼,并且決定couchbase的幾個(gè)新的特性也用c來(lái)寫(xiě)。令人驚異的是,顯然事實(shí)證明,c 語(yǔ)言提供了對(duì)于程序的良好控制能力,而我們因此更容易快速找出程序的問(wèn)題并進(jìn)行調(diào)試。長(zhǎng)遠(yuǎn)來(lái)看,c語(yǔ)言顯然具有良好的生產(chǎn)效率。
我總是告誡自己,我需要一個(gè)更加高效的可以替代c語(yǔ)言的東西。它只要可以修正程序里面那寫(xiě)毛糙的細(xì)節(jié)然后解決問(wèn)題就可以了。但是從事實(shí)來(lái)看,不論是從語(yǔ)法、從語(yǔ)義、從工具或者從“自頂至底”的開(kāi)發(fā)方法來(lái)看,沒(méi)有什么可以值得我們?yōu)橹垢冻雠?。到現(xiàn)在為止,c語(yǔ)言毫無(wú)疑問(wèn)的是最高效的語(yǔ)言,我認(rèn)為短期內(nèi)這不會(huì)有任何改變。
你可以在twitter上“推”我一下,然后就可以了解我對(duì)編程的一些看法以及couchbase的開(kāi)發(fā)進(jìn)度了~
原文鏈接:http://www.oschina.net/translate/the_unreasonable_effectiveness_of_c