最近,一場有趣的討論在微軟公司的Herb Sutter和Mono專案的Miguel de Icaza之間展開,話題是關於原生程式碼和Just-In-Time編譯器的優點對比,雙方對各自的觀點都提出了比較深刻見解。把他們的觀點彙總起來,其實就可以很好地反映出原生程式碼和受控程式碼的發展現狀。
Herb Sutter的觀點由他對於一個問題的回答而展開。這個問題是:“什麼時候,優秀的JIT技術才能拯救受控程式碼?”Sutter對此的觀點可總結如下:雖然C++和受控程式碼經常被人們拿來針鋒相對地比較,但是,這兩種語言在效能和生產力方面做出的基本權衡策略是完全不同的。
Sutter認為,C++的策略,主要是在側重在效能方面的提升,而不同的是,受控程式碼(也就是像Java/.NET這些基於虛擬機器的程式碼)則側重在如何提高程式設計師的生產力。更深一步,Sutter表示:首先,JIT編譯技術並不是問題的主要矛盾。主要矛盾來自於更根本的因素,受控語言在設計伊始就考慮如何提高程式設計師生產力方面深思熟慮,而不惜以犧牲程式的執行的效率為代價
Miguel de Icaza在瞭解了Sutter的觀點後,隨後也提出了自己的觀點。
“受控語言的設計者們在進行設計的時候,優先考慮的是語言的安全性問題,然後才是語言的效能。比如,對陣列的越界訪問是一種非法操作,當這種操作發生時,受控語言會讓程式立刻中止執行,而不是等到其直接造成系統崩潰,或者是留下巨大的安全隱患漏洞。”
在關於基於JIT的語言方面,兩位牛人對其是否能產生優化程式碼這一問題,有截然不同的觀點。
“其次,就算是JIT本身的問題,一個JIT編譯器產生的編譯程式碼肯定不可能比常規的優化編譯器產生的編譯程式碼更好。因為JIT編譯器的主要目的是怎麼讓程式編譯得更快,而不是如何產生優化的程式碼(讓其執行得更快)”,Herb Sutter這樣說道。
但是,我對上述的說法有點不贊同。總的來說,上面的說法對於早期的JIT編譯器沒有問題,而且Sutter所指的可能就正是Microsoft早期的.NET JIT編譯器。但是,現在的JIT編譯器已經完全不同於他理解中的那種了。 Miguel de Icaza迴應道。
de Icaza認為JIT編譯器必須迴應對產生程式碼質量的質疑:“…在產生程式碼質量和產生程式碼的速度的平衡性方面。JIT編譯器更加側重於如何縮短編譯程式碼的時間,而不是產生程式碼的質量。”然而,Mono允許使用者使用LLVM編譯框架,產生更高質量的程式碼。de Icaza註釋道:“【Mono使用者】LLVM編譯框架,也就是蘋果Mac OS Lion作業系統使用的編譯器,只要這個編譯器進步了,Mono產生的程式碼的質量也會隨之進步。”
選擇LLVM編譯框架做後端,能讓Mono使用者有機會根據他們特定專案的需要進行選擇,是要提高編譯的速度,還是要提高產生程式碼的質量。這就給專案提供了更大的靈活性,在開發進行中,需要反覆進行編譯的時候,可以選擇提高編譯速度來降低每次編譯的時間。當專案接近結束的時候,則可以選在提高編譯程式碼的質量,來提高終端使用者的體驗。
儘管JIT選擇更加側重語言的安全性,而不是語言的執行效率,但這並不意味著受控程式碼的執行時(runtime)執行效率將來不會改進。de Icaza提出了幾個可改進的方面,包括意向,擴充套件虛擬機器,限制動態語言特性,以及更好地支援語言特性和本地硬體之間的對映等等。
Sutter則發表了下列評論,作為他最初觀點的補充。他認為C++從根本上就具有效能優勢。
“就像‘保健品’和‘處方藥’這兩個東西有本質的區別一樣,在語言效能方面,C++永遠只是吃‘保健品’強身健體,而受控語言則是在吃‘處方藥’治病救人。受控語言採取了那麼多“卓越的手段”提升執行效能,也都是屬於吃藥治病的範疇。而且“保健品”吃得少,“處方藥”吃得多,這種局面是無法避免的。你無法忽略“保健”的作用(某種程度上,你先“保健”,如果“保健”不行,再吃藥也不遲。但是,如果你一開始不“保健”,等拖到需要“吃藥”的程度,這個時候再“保健”就沒有任何意義了。),如果你真的很在意程式的執行效能的控制,那就應該以優化程式執行效能為重(而不是用什麼辦法來補救效能的缺失)。
不知道讀者對C++和受控程式碼之間的權衡有什麼看法。開發者會推進受控程式碼不斷髮展,來彌補其在效能上的不足麼?新的C++標準的語言特性又是否需要重新審視一下受控程式碼開發者的觀點呢?
打賞支援我翻譯更多好文章,謝謝!
打賞譯者
打賞支援我翻譯更多好文章,謝謝!