WebAssembly及其API的知識(shí)點(diǎn)總結(jié)

這篇文章主要講解了“WebAssembly及其API的知識(shí)點(diǎn)總結(jié)”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“WebAssembly及其API的知識(shí)點(diǎn)總結(jié)”吧!

成都創(chuàng)新互聯(lián)專注于企業(yè)成都營(yíng)銷網(wǎng)站建設(shè)、網(wǎng)站重做改版、銅陵網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、html5、商城開發(fā)、集團(tuán)公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁(yè)設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性價(jià)比高,為銅陵等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。

什么是 WebAssembly?

在了解 WebAssembly 之前,讓我們看一下什么是 Assembly。

Assembly(匯編)是一種低級(jí)編程語(yǔ)言,它與體系結(jié)構(gòu)的機(jī)器級(jí)指令有著非常密切的聯(lián)系。換句話說,它只需一個(gè)進(jìn)程就可以轉(zhuǎn)換為機(jī)器可以理解的代碼,即機(jī)器代碼。此轉(zhuǎn)換過程稱為匯編。

WebAssembly可以簡(jiǎn)稱為 Web  的匯編。它是一種類似于匯編語(yǔ)言的低級(jí)語(yǔ)言,具有緊湊的二進(jìn)制格式,使您能夠以類似本機(jī)的速度運(yùn)行Web應(yīng)用程序。它還為C,C  ++和Rust等語(yǔ)言提供了編譯目標(biāo),從而使客戶端應(yīng)用程序能夠以接近本地的性能在Web上運(yùn)行。

此外,WebAssembly 的出現(xiàn)是與 JS 一起運(yùn)行,而不是取代 JS。使用 WebAssembly JavaScript  API,你可以交替地運(yùn)行來自任一種語(yǔ)言的代碼,來回沒有任何問題。這為我們提供了利用 WebAssembly 的強(qiáng)大功能和性能以及 JS  的通用性和適應(yīng)性的應(yīng)用程序。這為web應(yīng)用程序打開了一個(gè)全新的世界,它可以運(yùn)行最初并不打算用于web的代碼和功能。

有什么區(qū)別

Lin Clark預(yù)測(cè),2017年 WebAssembly 的引入可能會(huì)引發(fā) web 開發(fā)生命中的一個(gè)新的拐點(diǎn)。早期的另一個(gè)拐點(diǎn) 生在引入 JITs  編譯的時(shí)候,JIT 編譯使JS 的速度提高了近10倍。

如果將 WebAssembly 的編譯過程與 JS 的編譯過程進(jìn)行比較,會(huì)注意到幾個(gè)過程已被剝離,其余過程已被修剪,如下所示:

JIT 是使 JavaScript 運(yùn)行更快的一種手段,通過監(jiān)視代碼的運(yùn)行狀態(tài),把 hot 代碼(重復(fù)執(zhí)行多次的代碼)進(jìn)行優(yōu)化。通過這種方式,可以使  JavaScript 應(yīng)用的性能提升很多倍。

仔細(xì)比較上圖,注意到,重新參與WebAssembly已經(jīng)完全被剝奪掉了。這主要是因?yàn)榫幾g器不需要對(duì)WebAssembly代碼做任何假設(shè),因?yàn)橹T如數(shù)據(jù)類型是在代碼中明確提及。

但是 JS 不是這樣的,因?yàn)镴IT應(yīng)該做一些假設(shè)來運(yùn)行代碼,如果假設(shè)失敗,它需要重新優(yōu)化它的代碼。

如何獲取 WebAssembly 代碼

WebAssembly是一項(xiàng)偉大的技術(shù),我們需要如何利用 WebAssembly 的強(qiáng)大功能呢?

有幾種方法:

  • 不推薦從頭編寫 WebAssembly 代碼,除非你非常了解基本知識(shí)

  • 從 C 編譯為 WebAssembly

  • 從 C++ 編譯為 WebAssembly

  • 從 Rust 編譯為 WebAssembly

  • 使用 AssemblyScript 將 Typescript 編譯為WebAssembly。對(duì)于不熟悉C/C ++或Rust 的  Web開發(fā)人員來說,這是一個(gè)不錯(cuò)的選擇

  • 支持更多的語(yǔ)言選項(xiàng)。

此外,還有Emscripten和WebAssembly Studio之類的工具可以幫助您完成上述過程。

JS 的 WebAssembly API

為了充分利用 WebAssembly 的特性,我們必須將其與 JS 代碼集成在一起,這可以在JavaScript WebAssembly  API的幫助下完成。

模塊編譯和實(shí)例化

WebAssembly代  碼駐留在.wasm文件中。這個(gè)文件應(yīng)該被編譯成特定于它所運(yùn)行的機(jī)器的機(jī)器碼。我們可以使用WebAssembly.compile方法來編譯 WebAssembly  模塊。

WebAssembly.instantiate方法實(shí)例化已編譯模塊。另外,我們也可以從.wasm文件獲得的數(shù)組緩沖區(qū)傳遞到WebAssembly.instantiate方法中。這也適用,因?yàn)閷?shí)例化方法有兩個(gè)重載。

let exports  fetch('sample.wasm').then(response =>   response.arrayBuffer() ).then(bytes =>   WebAssembly.instantiate(bytes) ).then(results => {   exports = results.instance.exports })

上述方法的缺點(diǎn)之一是這些方法不能直接訪問字節(jié)碼,因此在編譯/實(shí)例化wasm模塊之前,需要采取額外的步驟將響應(yīng)轉(zhuǎn)換為ArrayBuffer。

相反,我們可以使用WebAssembly.compileStreaming /  WebAssembly.instantiateStreaming方法來實(shí)現(xiàn)與上述相同的功能,其優(yōu)點(diǎn)是可以直接訪問字節(jié)碼,而無需將響應(yīng)轉(zhuǎn)換為ArrayBuffer。

let exports  WebAssembly.instantiateStreaming(fetch('sample.wasm')) .then(obj => {   exports = obj.instance.exports })

注意,WebAssembly.instantiate和WebAssembly.instantiateStreaming會(huì)返回實(shí)例以及已編譯的模塊,它們可用于快速啟動(dòng)模塊的實(shí)例。

let exports; let compiledModule;  WebAssembly.instantiateStreaming(fetch('sample.wasm')) .then(obj => {   exports = obj.instance.exports;   //access compiled module   compiledModule = obj.module; })

導(dǎo)入對(duì)象

實(shí)例化 WebAssembly 模塊實(shí)例時(shí),可以選擇傳遞一個(gè)導(dǎo)入對(duì)象,該對(duì)象將包含要導(dǎo)入到新創(chuàng)建的模塊實(shí)例中的值,有 4 種類型:

  • global values

  • functions

  • memory

  • tables

可以將導(dǎo)入對(duì)象視為提供給模塊實(shí)例的工具,以幫助它實(shí)現(xiàn)其任務(wù)。如果沒有提供導(dǎo)入對(duì)象,編譯器將分配默認(rèn)值。

Global

WebAssembly.Global 對(duì)象表示一個(gè)全局變量實(shí)例, 可以被JavaScript 和importable/exportable 訪問  ,跨越一個(gè)或多個(gè)WebAssembly.Module 實(shí)例. 他允許被多個(gè)modules動(dòng)態(tài)連接.

可以使用WebAssembly.Global()構(gòu)造函數(shù)創(chuàng)建全局實(shí)例。

const global = new WebAssembly.Global({     value: 'i64',     mutable: true }, 20)

語(yǔ)法

var myGlobal = new WebAssembly.Global(descriptor, value)

global 構(gòu)造函數(shù)接受兩個(gè)參數(shù)。

descriptor

GlobalDescriptor 包含2個(gè)屬性的表:

  • value: A USVString 表示全局變量的數(shù)據(jù)類型. 可以是i32, i64, f32, 或 f64

  • mutable: 布爾值決定是否可以修改. 默認(rèn)是 false

value可以是任意變量值,需要其類型與變量類型匹配. 如果變量沒有定義, 使用0代替

const global = new WebAssembly.Global({     value: 'i64',     mutable: true }, 20);  let importObject = {     js: {         global     } };  WebAssembly.instantiateStreaming(fetch('global.wasm'), importObject)

全局實(shí)例應(yīng)該傳遞給importObject,以便在 WebAssembly 模塊實(shí)例中可以訪問它。

Memory

當(dāng) WebAssembly 模塊被實(shí)例化時(shí),它需要一個(gè) memory  對(duì)象。你可以創(chuàng)建一個(gè)新的WebAssembly.Memory并傳遞該對(duì)象。如果沒有創(chuàng)建 memory  對(duì)象,在模塊實(shí)例化的時(shí)候?qū)?huì)自動(dòng)創(chuàng)建,并且傳遞給實(shí)例。

JS引擎創(chuàng)建一個(gè)ArrayBuffer來做這件事情。ArrayBuffer 是 JS 引用的 JavaScript 對(duì)象。JS  為你分配內(nèi)存。你告訴它需要多少內(nèi)存,它會(huì)創(chuàng)建一個(gè)對(duì)應(yīng)大小的ArrayBuffer

ArrayBuffer 做了兩件事情,一件是做 WebAssembly 的內(nèi)存,另外一件是做 JavaScript 的對(duì)象。

它使 JS 和 WebAssembly 之間傳遞內(nèi)容更方便。

使內(nèi)存管理更安全。

Table

WebAssembly.Table() 構(gòu)造函數(shù)根據(jù)給定的大小和元素類型創(chuàng)建一個(gè)Table對(duì)象。

這是一個(gè)包裝了WebAssemble Table 的Javascript包裝對(duì)象,具有類數(shù)組結(jié)構(gòu),存儲(chǔ)了多個(gè)函數(shù)引用。在 JS  或者WebAssemble中創(chuàng)建Table 對(duì)象可以同時(shí)被JS 或WebAssemble 訪問和更改。

引入Table的主要原因是提高了安全性。我們可以使用set()、grow()和get()方法來操作表。

事例

為了演示,我將使用WebAssembly Studio應(yīng)用程序?qū)文件編譯為.wasm。

我已經(jīng)在wasm文件中創(chuàng)建了一個(gè)函數(shù)來計(jì)算一個(gè)數(shù)字的冪。我將必要的值傳遞給函數(shù),然后用JavaScript接收輸出。

同樣,我在wasm中進(jìn)行了一些字符串操作。需要注意,wasm沒有字符串類型。因此,它將使用ASCII值。返回到 JS  的值將指向存儲(chǔ)輸出的內(nèi)存位置。由于內(nèi)存對(duì)象是ArrayBuffer,因此我要進(jìn)行迭代,直到收到字符串中的所有字符為止。

JavaScript文件

let exports; let buffer; (async() => {   let response = await fetch('../out/main.wasm');   let results = await WebAssembly.instantiate(await response.arrayBuffer());   //or   // let results = await WebAssembly.instantiateStreaming(fetch('../out/main.wasm'));   let instance = results.instance;   exports = instance.exports;   buffer = new Uint8Array(exports.memory.buffer);    findPower(5,3);      printHelloWorld();    })();  const findPower = (base = 0, power = 0) => {   console.log(exports.power(base,power)); }  const printHelloWorld = () => {   let pointer = exports.helloWorld();   let str = "";   for(let i = pointer;buffer[i];i++){     str += String.fromCharCode(buffer[i]);   }   console.log(str); }

C 文件

#define WASM_EXPORT __attribute__((visibility("default"))) #include <math.h>   WASM_EXPORT double power(double number,double power_value) {   return pow(number,power_value); }  WASM_EXPORT char* helloWorld(){   return "hello world"; }

應(yīng)用

WebAssembly 更適合用于寫模塊,承接各種復(fù)雜的計(jì)算,如圖像處理、3D運(yùn)算、語(yǔ)音識(shí)別、視音頻編碼解碼這種工作,主體程序還是要用  javascript 來寫的。

感謝各位的閱讀,以上就是“WebAssembly及其API的知識(shí)點(diǎn)總結(jié)”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)WebAssembly及其API的知識(shí)點(diǎn)總結(jié)這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

分享題目:WebAssembly及其API的知識(shí)點(diǎn)總結(jié)
當(dāng)前網(wǎng)址:http://muchs.cn/article32/johjpc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計(jì)網(wǎng)站建設(shè)、網(wǎng)站改版、微信公眾號(hào)響應(yīng)式網(wǎng)站、品牌網(wǎng)站設(shè)計(jì)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作