免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
V8 Design Elements(翻譯)

V8 Design Elements(翻譯)

發(fā)表于5個(gè)月前(2013-08-14 15:43)   閱讀(28) | 評(píng)論(0 0人收藏此文章, 我要收藏
0
V8

最近開(kāi)始學(xué)習(xí)V8 Javascript引擎,這篇文章是翻譯官方文檔的,解釋了V8之所以快的主要原因等,原文請(qǐng)參見(jiàn)http://code.google.com/apis/v8/design.html

V8是一個(gè)新的為了提高Javascript程序速度的Javascript引擎,在多項(xiàng)測(cè)試中,V8的速度比JScript (in Internet Explorer), SpiderMonkey (in Firefox), and JavaScriptCore (in Safari)都要快很多倍,如果你的JS網(wǎng)絡(luò)應(yīng)用程序正受制于JS引擎的速度,那么使用V8而不是你現(xiàn)在使用的JS引擎將可以大幅改善你的應(yīng)用程序的表現(xiàn)。至于提升的幅度則由JS所占的比例以及JS的結(jié)構(gòu)(nature of JS)等多方面因素決定,例如,如果一個(gè)函數(shù)在你的應(yīng)用中將會(huì)被一次次重復(fù)運(yùn)行,那么提升的幅度將會(huì)比很多函數(shù)都在你的應(yīng)用中只運(yùn)行一次要大很多,至于會(huì)這樣的原因?qū)?huì)在后面的文章中解釋。

V8速度提升的三個(gè)主要方面為:

  • Fast Property Access (快速的屬性訪問(wèn))
  • Dynamic Machine Code Generation (動(dòng)態(tài)生成機(jī)器碼)
  • Efficient Garbage Collection (高效的垃圾回收)


快速的屬性訪問(wèn)

JS是一種動(dòng)態(tài)語(yǔ)言,對(duì)象的屬性(property)可以在運(yùn)行時(shí)被動(dòng)態(tài)的添加和刪除,這意味著對(duì)象的屬性很有可能被改變,絕大多數(shù)JS引擎采用一個(gè)字典型的數(shù)據(jù)結(jié)構(gòu)來(lái)存儲(chǔ)對(duì)象的屬性,每一次屬性的訪問(wèn)都需要一次動(dòng)態(tài)的查詢(xún)以獲得屬性在內(nèi)存中的位置,這樣的訪問(wèn)方法使得JS中的屬性訪問(wèn)要比普通編程語(yǔ)言例如Java和Smalltalk中的對(duì)象訪問(wèn)要慢很多,在這些(普通的)編程語(yǔ)言中,對(duì)象的屬性值根據(jù)類(lèi)的固定結(jié)構(gòu),被編譯器放在離對(duì)象指針有固定的偏移值的內(nèi)存位置上,屬性的訪問(wèn)只是一次簡(jiǎn)單的內(nèi)存讀取和寫(xiě)入,通常只需要一個(gè)(匯編)指令。

為了減少訪問(wèn)JS屬性的時(shí)間,V8沒(méi)有采用動(dòng)態(tài)查詢(xún)的方式,V8會(huì)在背后動(dòng)態(tài)的創(chuàng)建隱藏類(lèi),在V8中,當(dāng)對(duì)象的屬性改變時(shí),對(duì)象會(huì)更改隱藏類(lèi)的指向。這種方式的基本思想并不是被創(chuàng)新出來(lái)的,在prototype-based的編程語(yǔ)言Self中也做了類(lèi)似的事情,詳見(jiàn)An Efficient Implementation of Self, a Dynamically-Typed Object-Oriented Language Based on Prototypes

我們通過(guò)舉例來(lái)更加清楚的了解整個(gè)過(guò)程。請(qǐng)看下面這個(gè)很簡(jiǎn)單的JS函數(shù)。

1function Point(x, y) {
2    this.x = x;
3    this.y = y;
4}

當(dāng)new Point(x, y)被執(zhí)行的時(shí)候,一個(gè)新的Point對(duì)象會(huì)被創(chuàng)建,當(dāng)V8第一次執(zhí)行這個(gè)函數(shù)的時(shí)候,V8會(huì)為Point創(chuàng)建一個(gè)初始的隱藏類(lèi),為方便,我們假設(shè)這個(gè)類(lèi)叫C0,顯然這個(gè)類(lèi)里面什么都沒(méi)有,這個(gè)時(shí)候,Point這個(gè)對(duì)象的隱藏類(lèi)是C0。

當(dāng)執(zhí)行Point中的第一個(gè)語(yǔ)句(this.x = x;),會(huì)在Point對(duì)象中創(chuàng)建一個(gè)新的屬性x,對(duì)于V8而言,會(huì)做如下事情:

  • 創(chuàng)建另外一個(gè)隱藏類(lèi)C1,繼承自C0,同時(shí)在C1中加入屬性x,x的值會(huì)被存在離Point對(duì)象偏移0的地方。
  • 更新C0的描述,添加一個(gè)類(lèi)轉(zhuǎn)移,以后,如果一個(gè)隱藏類(lèi)指向C0的對(duì)象中加入了x屬性,那么這個(gè)對(duì)象的隱藏類(lèi)將會(huì)指向C1(這樣可以避免每次加入新屬性的時(shí)候都需要重新創(chuàng)建一個(gè)新的隱藏類(lèi),如果我們第二次調(diào)用Point函數(shù),就不會(huì)再次創(chuàng)建C1和C0類(lèi),而會(huì)直接使用這次創(chuàng)建的,這個(gè)也說(shuō)明了為什么如果一個(gè)函數(shù)在應(yīng)用中被重復(fù)運(yùn)行的話,那么速度的提升就會(huì)很大)。在這個(gè)時(shí)候,Point對(duì)象的隱藏類(lèi)指向C1


當(dāng)執(zhí)行Point中的第二個(gè)語(yǔ)句(this.y = y;)的時(shí)候,將會(huì)在Point對(duì)象中創(chuàng)建一個(gè)新的屬性y,對(duì)于V8而言,會(huì)做如下事情:

  • 創(chuàng)建一個(gè)新的隱藏類(lèi)C2,繼承自C1,同時(shí)對(duì)C2加入一個(gè)屬性y,存儲(chǔ)在離Point對(duì)象便宜1的內(nèi)存位置上。
  • 更新C1的描述,添加一個(gè)類(lèi)轉(zhuǎn)移,以后,如果一個(gè)隱藏類(lèi)指向C1的對(duì)象中加入了y屬性,那么這個(gè)對(duì)象的隱藏類(lèi)將會(huì)指向C2.

每次有一個(gè)屬性被添加的時(shí)候就要重新創(chuàng)建一個(gè)隱藏類(lèi)的做法看起來(lái)好像很低效,但是,因?yàn)轭?lèi)轉(zhuǎn)移的存在,隱藏類(lèi)可以被復(fù)用(如我上面所解釋?zhuān)?。盡管JS比其他面向?qū)ο蟮木幊陶Z(yǔ)言都要更加動(dòng)態(tài),但是采用上面的方法,通過(guò)觀察很多JS程序的運(yùn)行,它們?cè)诤艽蟪潭壬隙贾赜昧酥暗慕Y(jié)構(gòu)(the runtime behavior of most JS programs results in a high degree of structure-sharing using the above approach). 利用隱藏的方法有兩個(gè)好處:屬性的訪問(wèn)不再需要一個(gè)字典查詢(xún),同時(shí)可以讓V8使用一些在以類(lèi)為基礎(chǔ)的普通編程語(yǔ)言中可以用的優(yōu)化方法,例如inline caching(參考 Efficient Implementation of the Smalltalk-80 System)。

動(dòng)態(tài)生成機(jī)器碼

V8會(huì)JS代碼第一次運(yùn)行的時(shí)候?qū)⑵渲苯泳幾g為機(jī)器碼,在V8中沒(méi)有中間字節(jié)碼,也就沒(méi)有解釋器,屬性的訪問(wèn)由inline cache來(lái)完成,但這些代碼可能會(huì)在V8執(zhí)行期間被更改為別的機(jī)器指令。

當(dāng)?shù)谝淮螆?zhí)行訪問(wèn)某個(gè)對(duì)象的某個(gè)屬性的代碼的時(shí)候,V8決定這個(gè)對(duì)象現(xiàn)在的隱藏類(lèi),同時(shí)會(huì)進(jìn)行如下優(yōu)化,V8假設(shè)當(dāng)前代碼塊中的對(duì)這個(gè)對(duì)象的所有的屬性訪問(wèn)都會(huì)使用這個(gè)隱藏類(lèi),并根據(jù)這個(gè)假設(shè)修改inline cache的代碼,直接使用這個(gè)隱藏類(lèi)(跳過(guò)查詢(xún)隱藏類(lèi)的步驟),如果V8的假設(shè)是正確的,那么屬性值的讀取和賦值只需一個(gè)指令即可完成,如果假設(shè)錯(cuò)誤,那么V8再次修改代碼,移除這一優(yōu)化。

舉例,JS中訪問(wèn)一個(gè)Point對(duì)象的x屬性的代碼為

point.x

在V8中,相對(duì)應(yīng)的機(jī)器碼為

# ebx = the point objectcmp [ebx,<hidden class offset>],<cached hidden class>jne <inline cache miss>mov eax,[ebx, <cached x offset>]

如果這個(gè)對(duì)象的隱藏類(lèi)不符合緩存代碼中的隱藏類(lèi),執(zhí)行將會(huì)跳轉(zhuǎn)到V8運(yùn)行系統(tǒng)中處理inline cache失敗的地方并修改inline cache的代碼,如果找到了這個(gè)屬性,那么x的值就會(huì)直接被得到。

當(dāng)有許多對(duì)象共享同一個(gè)隱藏類(lèi)的時(shí)候,這樣的方法能夠使得JS的屬性訪問(wèn)速度和大部分靜態(tài)語(yǔ)言的訪問(wèn)速度相仿,使用隱藏類(lèi)并通過(guò)inline cache代碼來(lái)訪問(wèn)屬性,同時(shí)優(yōu)化機(jī)器碼的生成,V8能夠大幅優(yōu)化大部分JS代碼的執(zhí)行效率。

高效的垃圾回收

V8會(huì)將不再被引用的內(nèi)存進(jìn)行回收,這個(gè)過(guò)程通常被稱(chēng)之為垃圾回收,為了保證快速的對(duì)象生成,縮短垃圾回收所造成的暫停,并且防止內(nèi)存碎片的產(chǎn)生,V8的垃圾回收器使用了如下原則:stop-the-world, generational, accurate。具體來(lái)說(shuō):

  • 當(dāng)處在垃圾回收循環(huán)中時(shí),停止程序的執(zhí)行
  • 在大多數(shù)垃圾回收循環(huán)中僅僅處理一部分的堆內(nèi)存,這樣做最小化了程序停止所帶來(lái)的影響
  • 永遠(yuǎn)知道所有對(duì)象和指針在內(nèi)存中的位置,這個(gè)避免了不正確的垃圾回收器中普遍存在的內(nèi)存泄露的問(wèn)題。

在V8中,對(duì)象堆內(nèi)存被分為兩部分,用于新對(duì)象創(chuàng)建的新的內(nèi)存空間,用于存放在垃圾回收周期中存留下來(lái)的對(duì)象,如果一個(gè)對(duì)象在垃圾回收中被移動(dòng)了,V8會(huì)更新所有指向改對(duì)象的指針。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶(hù)發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
V8 JS引擎
V8 Javascript 引擎設(shè)計(jì)理念
JavaScript內(nèi)部原理:瀏覽器的內(nèi)幕
詳解js閉包
js 動(dòng)態(tài)取json對(duì)象的屬性
JS
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服