WebAssembly的起源及實(shí)踐分析
大小:0.9 MB 人氣: 2017-09-30 需要積分:2
推薦 + 挑錯(cuò) + 收藏(0) + 用戶評(píng)論(0)
標(biāo)簽:JAVA(102450)webassemly(1576)
在瀏覽器之爭(zhēng)中,Chrome憑借Java的卓越性能取得了市場(chǎng)主導(dǎo)地位,然而由于Java的無(wú)類(lèi)型特性,導(dǎo)致其運(yùn)行時(shí)消耗大量的性能做為代價(jià),這也是Java的瓶頸之一。WebAssembly旨在解決這一問(wèn)題。本文從WebAssembly的起源到開(kāi)發(fā)實(shí)踐對(duì)其做全面探究,幫助開(kāi)發(fā)者對(duì)WebAssembly有全面的了解。緣起
讓我們從瀏覽器大戰(zhàn)說(shuō)起。微軟憑借Windows系統(tǒng)捆綁Internet Explorer的先天優(yōu)勢(shì)擊潰Netscape后,進(jìn)入了長(zhǎng)達(dá)數(shù)年的靜默期。而Netscape則于1998年將Communicator開(kāi)源,并由Mozilla基金會(huì)衍生出Firefox瀏覽器,在2004年發(fā)布了1.0版本。從此,第二次瀏覽器大戰(zhàn)拉開(kāi)帷幕。這場(chǎng)大戰(zhàn)由Firefox瀏覽器領(lǐng)銜,Safari、Opera等瀏覽器也積極進(jìn)取,Internet Explorer的主導(dǎo)地位首次受到挑戰(zhàn)。2008年Google推出Chrome瀏覽器,不但逐步侵蝕Firefox的市場(chǎng),更是壓制了老邁的Internet Explorer。在此次大戰(zhàn)之后的2012年,StatCounter的數(shù)據(jù)指出Chrome以微弱優(yōu)勢(shì)超越Internet Explorer成為世界上最流行的瀏覽器。
分析Google Chrome瀏覽器戰(zhàn)勝I(mǎi)nternet Explorer的原因,除了對(duì)Web標(biāo)準(zhǔn)更友善的支持外,卓越的性能是其中相當(dāng)重要的因素,而瀏覽器性能之爭(zhēng)的本質(zhì)則體現(xiàn)在Java引擎。此前,Java引擎的實(shí)現(xiàn)方式經(jīng)歷了遍歷語(yǔ)法樹(shù)到字節(jié)碼解釋器等較為原始的方式,將每條源代碼翻譯成相應(yīng)的機(jī)器碼并執(zhí)行,并不保存翻譯后的機(jī)器碼,使得解釋執(zhí)行很慢。2008年9月,Google發(fā)布了V8 Java引擎。V8被設(shè)計(jì)用于提高Web瀏覽器中Java的執(zhí)行性能,通過(guò)即時(shí)編譯JIT(Just-In-Time)技術(shù),在執(zhí)行時(shí)將Java代碼編譯成更為高效的機(jī)器代碼并保存,下次執(zhí)行同一代碼段時(shí)無(wú)需再編譯,使得Java獲得了幾十倍的性能提升。
然而,Java是個(gè)無(wú)類(lèi)型(untyped,變量沒(méi)有類(lèi)型)的語(yǔ)言,這直接導(dǎo)致表達(dá)式c=a+b有多重含義:
a、b均為數(shù)字,則算術(shù)運(yùn)算符+表示值相加;
a、b為字符串,則+運(yùn)算符表示字符串連接;
……
表達(dá)式執(zhí)行時(shí),JIT編譯器需要檢查a和b的類(lèi)型,確定操作行為。若a、b均為數(shù)字,JIT編譯器則將a、b確認(rèn)為整型,而一旦某一變量變成字符串,JIT編譯器則不得不將之前編譯的機(jī)器碼推倒重來(lái)。由此可見(jiàn),Java的無(wú)類(lèi)型特性建立在消耗大量性能代價(jià)的基礎(chǔ)之上。即便JIT編譯器在對(duì)變量類(lèi)型發(fā)生變化時(shí)已進(jìn)行相應(yīng)優(yōu)化,但仍然有很多情況Java引擎未進(jìn)行或無(wú)法優(yōu)化,例如for-of、try-catch、try-finally、with語(yǔ)句以及復(fù)合let、const賦值的函數(shù)等。
由此可見(jiàn),Java的無(wú)類(lèi)型是Java引擎的性能瓶頸之一,改進(jìn)方案有兩種:一是設(shè)計(jì)一門(mén)新的強(qiáng)類(lèi)型語(yǔ)言并強(qiáng)制開(kāi)發(fā)者進(jìn)行類(lèi)型指定;二是給現(xiàn)有的Java加上變量類(lèi)型。
微軟開(kāi)發(fā)的Type屬于第一種改進(jìn)方案。它是擴(kuò)展了Java特性的語(yǔ)言,包含了類(lèi)型批注,編譯時(shí)類(lèi)型檢查,類(lèi)型推斷和擦除等功能,Type開(kāi)發(fā)者在聲明變量時(shí)指定類(lèi)型,使得Java引擎能夠更快將這種強(qiáng)類(lèi)型的語(yǔ)言編譯成弱類(lèi)型。
看看第二種方案:
代碼1
代碼1表示帶有兩個(gè)參數(shù)(a和b)的Java函數(shù),和通常Java代碼不同的地方在于a=a | 0及b=b | 0,以及返回值后面均利用標(biāo)注進(jìn)行了按位OR操作。這么做的優(yōu)點(diǎn)是使Java引擎強(qiáng)制轉(zhuǎn)換變量的值為整型執(zhí)行。通過(guò)標(biāo)注加上變量類(lèi)型,Java引擎就能更快地編譯。
既然增加變量類(lèi)型能夠提升Web性能,有沒(méi)有辦法將靜態(tài)類(lèi)型代碼例如C/C++等轉(zhuǎn)換成Java指令的子集呢?上面的這段代碼恰恰是作為Java子集的asm.js,由代碼2的C語(yǔ)言編譯而來(lái):
代碼2
事實(shí)上,早在1995年起就已經(jīng)有Netscape Plugin API(NPAPI)在內(nèi)的可以使用瀏覽器運(yùn)行C/C++程序的項(xiàng)目在開(kāi)發(fā)。而2013年問(wèn)世的asm.js是目前較為廣泛的方案。asm.js是一種中間編程語(yǔ)言,允許用C/C++語(yǔ)言編寫(xiě)的計(jì)算機(jī)軟件作為Web應(yīng)用程序運(yùn)行,并保持更好的性能,而Mozilla Firefox從版本22起成為第一個(gè)為asm.js特別優(yōu)化的網(wǎng)頁(yè)瀏覽器。
Google也同樣在為原生代碼運(yùn)行在Web端而努力。Google Native Client(NaCl)采用沙盒技術(shù),讓Intel x86、ARM或MIPS子集的機(jī)器碼直接在沙盒上運(yùn)行。它能夠在無(wú)需安裝插件的情況下從瀏覽器直接運(yùn)行原生可執(zhí)行代碼,使Web應(yīng)用程序可以用接近于機(jī)器碼運(yùn)作的速度來(lái)運(yùn)行。而Google Portable Native Client(PNaCl)則稍有變化,通過(guò)一些前端編譯器將C/C++源代碼編譯成LLVM的中間字節(jié)碼而不是x86或ARM代碼,并且進(jìn)行優(yōu)化以及鏈接。
非常好我支持^.^
(0) 0%
不好我反對(duì)
(0) 0%