四虎精品视频-四虎精品成人免费网站-四虎黄色网-四虎国产视频-国产免费91-国产蜜臀97一区二区三区

為什么我支持托管運行時(虛擬機)

  最近博客園上在炒關于C#性能的問題,其實應該說是.NET性能的問題,其中某位仁兄提出,他希望C#能夠直接編譯為原生代碼,而不是在CLR這樣一個托管運行時上執行,因為虛擬機啊,JIT什么的性能差。后來發到TL上以后,也有朋友認為,“基于虛擬機的語言都是大公司為了利益在推動,說白了就是政治”,因此“對C#提高性能的建議感到可笑,因為它本來就不是用來開發高性能程序的”,再有,“C、C++已經明確不和這些后進爭所謂的‘容易開發’的頭銜”,那么其他語言為什么要和C++它們比較性能呢?我是托管運行時,或者虛擬機的忠實擁護者,這里談一下我在這方面的看法。

  我并不反對編譯為原生代碼的語言,尤其是C語言,它的意義在于提供了一種對硬件完全控制的手段,對硬件提供了一種最直接的抽象,幾乎可以映射到最終流程控制方式,因此無可替代。C++作為C語言的超集,提供了更豐富的抽象能力(如面向對象和模版化),只是語言本身過于復雜,超過了以我的智商可以承受的范圍,因此我學了幾次都沒怎么學會,現在更是忘得差不多了。不過我認為,越來越多的語言會構建在托管平臺上,而不是直接編譯成原生代碼。因為一個統一的托管運行時會帶來很多好處。

  首先,統一運行時提供了跨平臺的能力,Java便是一典型。.NET上有mono,使用也很廣泛,也有不少Unity3D,Gnome DO等成功案例。Novell,包括其他一些公司也在銷售基于mono的商業產品(如MonoTouch及Infragistics的ASP.NET Controls組件),我本身也在兩年多前就在生產環境上使用了mono,您現在看到的這個博客也是基于Ubuntu Server、mono 2.6 、Apache以及微軟開源ASP.NET MVC 2構建的。雖說從某些層面(如API兼容性)上說,mono的跨平臺性遠不如Java平臺,但它也是一個比較成熟的執行環境,并具備相當程度的跨平臺能力——尤其是在mono上開發,MS .NET上運行的時候(雖然我不建議這么做)。如今支持mono的產品、類庫數不勝數,我時常調侃道,“如果您的產品不支持mono,還真不好意思和人打招呼”。只可惜,不少人都用一些“不是親娘生的”類似的調調來否定mono,在我看來沒有經過調查研究的看法只能屬于“臆斷”,而且更是一種FUD了。

  即便退一步來說,我們不“跨操作系統”吧。有人說,.NET就支持Windows么,何必搞個虛擬機,還JIT那么麻煩。但事實上,“跨平臺”并非指的是簡單的“跨操作系統”,而是“跨執行環境”,如Silverlight。事實上,跨計算機體系結構本身也是種跨平臺(當然,操作系統其實已經進行了一定的統一抽象了)。因此,虛擬機的目的,是為上層執行體抽象出了統一的運行環境——這其實還是跨平臺,這平臺不僅僅是指操作系統,整體運行環境之間的差異也是運行時所“抽象”的一部分。比如在并發環境中,不同CPU架構的流水線上的亂序方式不一樣,同樣的代碼執行的效果就可能不同。最典型的例子,便是JVM之前的內存一致性模型控制的比較寬松,導致經典的double check模式在某些CPU上是會失敗的。現在Java標準也變得嚴格了,和.NET CLR一樣避免了Store Reordering。這意味著在某些CPU上,會在特定的地方加上Memory Barrier保證執行效果的一致性。在我看來這是更好的可移植性。C++或是C語言等實現“可移植性”的方式,往往是通過為不同環境提供不同的編譯器,生成不同的結果,而且會使用“宏”等方式,在代碼里寫出有平臺針對性的代碼。

  有了統一的運行時,也可以讓多語言互操作更為容易,如果沒有JVM或CLR,就很難像現在這么輕松地在Scala/Java/Jython/JRuby,或是C#/F#/IronPython/IronRuby,甚至是未來的語言之間進行直接地互操作,更難做到“無縫集成”了。在合適的場景下選用合適的語言,是提高生產力的重要手段。如果沒有JVM平臺,就很難使用Scala來代替Java這樣的劣質語言,而現在Scala便能夠保證充分利用Java平臺上類庫等積淀。

  有了“多語言”,那么便會引出虛擬機的另一個作用:讓語言實現者和虛擬機實現者的工作可以分離開來,各自優化。虛擬機的實現者可以盡力優化虛擬機的各種表現,為虛擬機加入各種優化措施,而無需讓虛擬機的上層語言分別調整。例如JVM性能提高之后,ScalaJava、Jython、JRuby等語言的性能都可以提高,否則各種語言分別優化的代價太高了(當然某些情況還是需要特殊對待的)。要說這方面的實例,在.NET平臺上有個開源的組件DLR(動態語言運行時),是在CLR上提供編寫動態語言的統一輔助類庫。以前它有個缺點,便是啟動速度比較慢,因為動態代碼的JIT耗時較長,而動態語言的很多場景是“即用即拋”的。后來,DLR增加了一個優化策略,便是一開始直接對抽象語法樹直接解釋執行,而執行多次之后才使用后臺線程將代碼JIT成原生代碼。有了如此改進,基于DLR的動態語言,如IronRuby和IronPython的啟動速度都提高了。

  虛擬機/運行時本身可以做的優化也很多,如果真覺得性能不夠,那么完全可以在運行前在本地編譯成native code,這和直接從源代碼變成native code從結果上看沒什么區別。但是現實是,很少有人去這么做,因為這么做往往只是節省了JIT的開銷,對性能提高效果不大。在不同環境中,此外還有各種優化,比如使用解釋執行,而不是JIT以次節省內存消耗,或是在運行時回收JIT的代碼(印象中在.NET Compact Framework里有這樣的策略,求詳情),或是在運行時根據代碼邏輯進行二次編譯。下面會談一個例子。另一種典型的優化,一直在研究卻還沒有真正實現的,虛擬機便是“自動并行”。關于這點,Anders在上次的演講中多次提到過,要實現這點還需要有各種支持,如聲明式編程,提供“無副作用”標記,甚至在語言級別的支持等等。

  之前那位朋友提到,C/C++已經明確不與后進語言比生產力了,后進語言也沒辦法和它們比較性能。對這個觀點我持保留意見,因為基于虛擬機的做法,其優化空間還有很多,理論上也可以做到更為徹底,在許多情況下性能完全有超越靜態編譯語言的可能。這是許多人的看法,而事實也是如此,在某些場景下Java的性能也已經超過了C++。如回到上面的二次編譯優化,對于性能優化也大有好處。舉一個簡單的例子,面向對象語言會出現很多虛方法調用(尤其是在符合一些關于設計的最佳實踐時,如“基于抽象編程”),調用需方法需要查方法表找方法入口,最普通的做法就是必須每次根據對象的實際類型查找方法表,找到地址,然后調用。偽代碼如下:

根據實際類型找到函數入口
調用

NET技術為什么我支持托管運行時(虛擬機),轉載需保留來源!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

主站蜘蛛池模板: 乔治桑| 草神纳西妲图片| 帅气动漫头像| 《韩国小姐》| 李轻扬| 韶山研学心得体会800高中| 高嘉慧| 同志电影网站| 胭脂似火电视剧免费观看完整版全集| 40集电视连续剧人生之路| 87版七仙女台湾| 荒笛子简谱| 《竹升妹之以牙还牙》| 圣洁四人行| 金时厚| river flows in you吉他谱| 免费看污视频| 加藤视频下载| 《保姆妈妈》电视剧| 经典常谈周易第二读书笔记| 视频www| 满宫春电影| 天津电视台体育频道节目单| 游吟诗人| 五年级必考歇后语大全| 念亲恩简谱| 色戒在线视频观看| 杨欣悦| 张艺馨个人资料| 博多之子| 最贵的烟前十名| 聊斋艳谭之荷花三娘子| 不潮不花钱歌词| 任喜宝| 咖啡爱上香草电视剧| 15j401图集电子版免费查看| 极品美女在线视频| 甜蜜杀机 电影| 陈奂生上城| 李慧珍演的电影有哪些| 混的头像|