<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 業(yè)界動態(tài) > 編程語言的發(fā)展趨勢及未來方向(4):動態(tài)語言

          編程語言的發(fā)展趨勢及未來方向(4):動態(tài)語言

          作者: 時間:2017-04-10 來源:網絡 收藏

            這是Anders Hejlsberg(不用介紹這是誰了吧)在比利時TechDays 2010所做的開場演講。由于最近我在博客上關于語言的討論比較多,出于應景,也打算將Anders的演講完整地聽寫出來。在上一部分中,Anders談及了聲明式編程的另一個重要組成部分:函數式編程,并使用.NET平臺上的函數式F#進行了演示。在這一部分中,Anders討論了動態(tài)語言及JavaScript的相關內容,“動態(tài)性”也是Anders眼中的發(fā)展趨勢之一。

          本文引用地址:http://www.ex-cimer.com/article/201704/346374.htm

            如果沒有特別說明,所有的文字都直接翻譯自Anders的演講,并使用我自己的口語習慣表達出來,對于Anders的口誤及反復等情況,必要時在譯文中自然也會進行忽略。為了方便理解,我也會將視頻中關鍵部分進行截圖,而某些代碼演示則會直接作為文章內容發(fā)表。

            (聽寫開始,接上篇)

             

           

            我下面繼續(xù)要講的是動態(tài)語言,這也是我之前提到的三種趨勢之一。

             

           

            我還是嘗試著去找到動態(tài)語言的定義,但是你也知道……一般地說,動態(tài)語言是一些不對編譯時和運行時進行嚴格區(qū)分的語言。這不像一些靜態(tài),比如C#,你先進行編譯,然后會得到一些編譯期錯誤,稍后再執(zhí)行,而對于動態(tài)語言來說這兩個階段便混合在一起了。我們都熟悉一些動態(tài)語言,比如JavaScript,,Ruby,LISP等等。

             

           

            動態(tài)語言有一些優(yōu)勢,而靜態(tài)語言也有著另一些優(yōu)勢,這也是兩個陣營爭論多年的內容。老實講,我認為結果不是兩者中的任意一個,它們都有各自十分重要的優(yōu)點,而長期來看,我認為結果應該是兩者的雜交產物,我認為在語言發(fā)展中也可以看到這樣的趨勢,這兩部分內容正在合并。

             

           

            許多人認定動態(tài)語言執(zhí)行起來很慢,也沒有類型安全等等。我想在這里觀察并比較一下,究竟是什么原因會讓靜態(tài)語言和動態(tài)語言在這方面有不同的性質。這里有一段有趣的代碼,它的語法在JavaScript和C#里都是正確的,這樣我們便能比較兩種語言是如何處理這段代碼的。

             

            首先我們把它看作是一段C#代碼,它只是用for循環(huán)把一堆整數相加,你肯定不會這么做,這只是一個示例。在C#中,當我們使用var關鍵字時,它表示“請為我推斷這里的類型”,所以在這里a和i的類型都是int。

            這斷代碼在執(zhí)行的時候,這兩個值都是32位整數,而for循環(huán)只是簡單的使用ADD指令即可,執(zhí)行起來自然效率很高。

            但如果從JavaScript或是動態(tài)語言的角度來看……或者說對于動態(tài)類型的語言來說,var只代表了“一個值”,它可以是任意類型,我們不知道它究竟是什么。所以當我們使用var a或var i時,我們只是定義了兩個值,其中包含了一個“類型”標記,表明在運行時它是個什么類型。在這里它是一個int,因此包含了存儲int值的空間。但有些時候,例如要存儲一個double值,那么可能便需要更多的空間,還可能是一個字符串,于是便包含一個引用。

            所以兩者的區(qū)別之一便是,表示同樣的值在動態(tài)語言中會有一些額外的開銷,代價較高。而在如今的CPU中,“空間”便等于“速度”,所以較大的值便需要較長時間進行處理,這里便損失了一部分效率。

            在JavaScript中,我們如果要處理a加i,那么便不僅僅是一個ADD指令。首先它必須查看兩個變量中的類型標記,然后根據類型選擇合適的相加操作。于是再去加載兩個值,然后再進行加法操作。這里還需要進行越界檢查,因為在JavaScript中一旦越界了便要使用double,等等。很明顯在這里也有許多開銷。一般來說,動態(tài)語言是使用解釋器來執(zhí)行的,因此還有一些解釋器需要的二進制碼。你把這些開銷全部加起來以后,便會發(fā)現執(zhí)行代碼時需要10倍到100倍的開銷。

            不過由于近幾年來出現的一些動態(tài)虛擬機或引擎,目前這些情況改善了許多。比方說,這是傳統(tǒng)的情況(上圖左),如在IE 6或IE 7里使用的非常緩慢的解釋器。目前的情況是,大部分的JavaScript引擎使用了JIT編譯器(上圖中),于是便省下了解釋器的開銷,這樣性能損失便會減小至3到10倍。而在過去的兩三年間,JIT編譯器也變得越來越高效,瀏覽器中新一代的適應性JIT編譯器(上圖右),如TraceMonkey,V8,還有如今微軟在IE 9中使用的Chakra引擎。這種適應性的JIT編譯器使用了一部分有趣的技術,如Inline Caching、Type Specialization、Hidden Classes、Tracing等等,它們可以將開銷降低至2到3倍的范圍內,這種效率的提升可謂十分神奇。

            在我看來,JavaScript引擎可能已經接近了性能優(yōu)化的極限,我們在效率上可以提升的空間已經不多。不過我同樣認為,如今JavaScript語言的性能已經足夠快了,完全有能力統(tǒng)治Web客戶端。

            有人認為,JavaScript從來不是一種適合進行大規(guī)模編程的語言。如今也有一些有趣的工具,如Google Web Tookit,在微軟Nikhil Kothari也創(chuàng)建了Script#,讓你可以編寫C#或Java代碼,然后將代碼編譯成JavaScript,這就像是將JavaScript當作是一種中間語言。Google Wave的所有代碼都用GWT寫成,它的團隊堅持認為用JavaScript不可能完成這樣的工作,因為復雜度實在太高了。如今在這方面還有一些有趣的開發(fā)成果,我不清楚什么時候會結束。不過我認為,這些都不算是大規(guī)模的JavaScript開發(fā)方案,而編寫C#或Java代碼再生成JavaScript的方式也不能算是完全正確的做法。我們可以關注這方面的走向。

            在.NET 4.0的運行時進行動態(tài)編程時,我們引入了一個新功能:動態(tài)語言運行時??梢赃@樣理解,CLR的目的是為靜態(tài)類型的編程語言提供一個統(tǒng)一的框架或編程模型,而DLR便是在.NET平臺上為動態(tài)語言提供了統(tǒng)一的編程模型。CLR本身已經有一些支持動態(tài)編程能力,如反射,Emit等等。不過在.NET上實現動態(tài)語言的時候,總會一遍又一遍地去實現某些功能,還有如動態(tài)語言如何與靜態(tài)語言進行交互,這些都由DLR來提供。DLR的特性包含了,如表達式樹、動態(tài)分發(fā)、Call Site緩存,這可以提高動態(tài)代碼的執(zhí)行效率。

            在.NET 4.0中我們使用了DLR,不僅僅是Iron和IronRuby,還有C# 4和VB.NET 10,它們使用DLR實現動態(tài)分發(fā)功能。因此我們共享了語言的動態(tài)能力實現方式,于是這些語言之間可以輕松地進行交互。同樣我們可以與其他多樣性的技術進行交互,例如使用JavaScript操作Silverlight的DOM,或是與Ruby、代碼溝通,甚至用來控制Office等自動化服務。



          關鍵詞: 編程語言 Python

          評論


          相關推薦

          技術專區(qū)

          關閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();