1. 程式人生 > >語言越低階,執行效率就越高嗎?

語言越低階,執行效率就越高嗎?

本來我是要繼續寫我的foreach系列文章的另外兩篇的。但是看了評C#事件處理,有一些感觸。

我不同意大家關於語言越低階,執行效率就越高的說法。
語言越低階,編譯器能夠決定的東西就越少,就越不能很好的優化執行程式碼。大家想想為什麼c語言編譯器,一般都忽略register關鍵字,C++一般都忽略inline關鍵字? 很多時候,編譯器只要掌握了足夠的資訊,就能做出明智的決定。
以前我測過delphi和C++生成的程式碼,delphi的程式碼比C++高效得多。因為C/C++裡廣泛使用了指標,對於變數的位置,struct中各個成員的排列方法,呼叫約定,對於編譯器都有非常嚴格的限制。編譯器只能忠實的翻譯,錯失了很多優化程式碼的機會。為了能夠享受各種程式碼優化技術,C++編譯器都提供了非常多的編譯優化選項,但是絕大部分都不是100%安全的。因為C/C++程式設計師總是可以越權完成很多低階操作。比如:用const修飾的變數是不會被修改的,編譯器可以利用這個知識將這個變數的值快取在暫存器中。但是在C++中,就不能做這項優化,因為C++程式設計師可以強制cast掉const限制。也許大家認為編譯器能夠監測到這種cast,自動關掉這項優化,但是誰能保證其它.obj檔案裡的程式碼有沒有修改這個const變數呢?

同樣類的私有成員,在C++中也很難真正實現訪問跟蹤。編譯器沒有100%確信的知識,怎麼能去優化呢?

世界上最好的汽車是手工打造的,但是不是說手工打造的汽車就一定比工業批量造出的汽車好。

我想寫程式最重要的是如何最清晰的表達我們要解決的問題,而不要過多的體現解決問題的次要細節。我們要的是報表、訂單;而不是記憶體,指標,函式。如果我們能從更高、更抽象的層次描述問題,就會留給底層軟體更多發揮的空間。比如底層軟體可以選擇低執行效率,極高開發效率的方法完成功能,而快速的製作原形,展示設計;或者底層軟體選擇高速執行的策略,面向執行時間要求高的場合;或者選擇低記憶體佔用作為目標,等等。

規則不是約束創造性地力量,而是激發創造性地基礎。沒有穩定的規則,哪裡會有什麼創造?我認為.net規則,是激發創造的開始,是一個新的世界的開始。

有人質疑C#完成事件模型太隱晦,臃腫,和il不直接對應,太複雜。event關鍵字完成了多播事件、非同步事件。想想java為了實現多播事件,明確的使用了列表。雖然C#也使用列表實現多播,但是使用列表這個事實並沒有明確的在語法上體現出來。這有什麼不同呢?這當然不同!在delegate中只有一個函式指標時,這個列表是不生成的,而且呼叫也是直接的,並沒有一個呼叫迴圈。另外,C#通過delegate還可以實現非同步事件,統一了非同步I/O的程式設計模型,最近Ado.net也執行非同步執行sql語句了。Java事件的interface實現,要完成非同步事件不知道要使用多少程式碼。而且只要程式碼一旦寫成,它就死了,執行環境就不能再做進一步的優化了。

比如做出租車,如果告訴司機你的目標地點,司機就可以綜合道路的長度、擁堵情況、路況情況選擇一個優化解。相反,如果告訴司機你的路線,那麼一切都固定了,僵化了,司機擁有再多的知識,都無法用上了。高階語言和低階語言之間的差別就和這個現實生活的例子是一個道理。也許很多人不同意,認為自己既是乘客也是司機。但是你認為自己真的對所有的計算機知識都瞭解嗎?CPU的不同,Cache效率的不同,匯流排效率的不同。硬體影響軟體的要素已經非常多,軟體的影響就更多了。現代的軟體會依賴大量的作業系統的呼叫、庫函式呼叫、編譯器等等,誰能知道在數以萬計的函式中,那一個效率高,那一個效率低。我們優化了數週程式碼獲得的效能提升,會被一個設計糟糕的庫函式輕易吞沒。就算優化好了一個系統,換一個環境還是效率高的嗎?比如使用者機器更換了顯示卡驅動程式?誰都不會有能力做一個好司機。

讓真正擁有實際執行知識的C#語言、.net執行環境來替我們完成95%的效能優化吧,我們能做一個好乘客,說清楚我們的目的地,就是極大的成功了。