中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

WebAssembly及其API的知識點總結

發布時間:2021-10-25 15:53:19 來源:億速云 閱讀:154 作者:iii 欄目:編程語言

這篇文章主要講解了“WebAssembly及其API的知識點總結”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“WebAssembly及其API的知識點總結”吧!

什么是 WebAssembly?

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

Assembly(匯編)是一種低級編程語言,它與體系結構的機器級指令有著非常密切的聯系。換句話說,它只需一個進程就可以轉換為機器可以理解的代碼,即機器代碼。此轉換過程稱為匯編。

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

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

有什么區別

Lin Clark預測,2017年 WebAssembly 的引入可能會引發 web 開發生命中的一個新的拐點。早期的另一個拐點 生在引入 JITs  編譯的時候,JIT 編譯使JS 的速度提高了近10倍。

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

JIT 是使 JavaScript 運行更快的一種手段,通過監視代碼的運行狀態,把 hot 代碼(重復執行多次的代碼)進行優化。通過這種方式,可以使  JavaScript 應用的性能提升很多倍。

仔細比較上圖,注意到,重新參與WebAssembly已經完全被剝奪掉了。這主要是因為編譯器不需要對WebAssembly代碼做任何假設,因為諸如數據類型是在代碼中明確提及。

但是 JS 不是這樣的,因為JIT應該做一些假設來運行代碼,如果假設失敗,它需要重新優化它的代碼。

如何獲取 WebAssembly 代碼

WebAssembly是一項偉大的技術,我們需要如何利用 WebAssembly 的強大功能呢?

有幾種方法:

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

  • 從 C 編譯為 WebAssembly

  • 從 C++ 編譯為 WebAssembly

  • 從 Rust 編譯為 WebAssembly

  • 使用 AssemblyScript 將 Typescript 編譯為WebAssembly。對于不熟悉C/C ++或Rust 的  Web開發人員來說,這是一個不錯的選擇

  • 支持更多的語言選項。

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

JS 的 WebAssembly API

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

模塊編譯和實例化

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

WebAssembly.instantiate方法實例化已編譯模塊。另外,我們也可以從.wasm文件獲得的數組緩沖區傳遞到WebAssembly.instantiate方法中。這也適用,因為實例化方法有兩個重載。

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

上述方法的缺點之一是這些方法不能直接訪問字節碼,因此在編譯/實例化wasm模塊之前,需要采取額外的步驟將響應轉換為ArrayBuffer。

相反,我們可以使用WebAssembly.compileStreaming /  WebAssembly.instantiateStreaming方法來實現與上述相同的功能,其優點是可以直接訪問字節碼,而無需將響應轉換為ArrayBuffer。

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

注意,WebAssembly.instantiate和WebAssembly.instantiateStreaming會返回實例以及已編譯的模塊,它們可用于快速啟動模塊的實例。

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

導入對象

實例化 WebAssembly 模塊實例時,可以選擇傳遞一個導入對象,該對象將包含要導入到新創建的模塊實例中的值,有 4 種類型:

  • global values

  • functions

  • memory

  • tables

可以將導入對象視為提供給模塊實例的工具,以幫助它實現其任務。如果沒有提供導入對象,編譯器將分配默認值。

Global

WebAssembly.Global 對象表示一個全局變量實例, 可以被JavaScript 和importable/exportable 訪問  ,跨越一個或多個WebAssembly.Module 實例. 他允許被多個modules動態連接.

可以使用WebAssembly.Global()構造函數創建全局實例。

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

語法

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

global 構造函數接受兩個參數。

descriptor

GlobalDescriptor 包含2個屬性的表:

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

  • mutable: 布爾值決定是否可以修改. 默認是 false

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

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

全局實例應該傳遞給importObject,以便在 WebAssembly 模塊實例中可以訪問它。

Memory

當 WebAssembly 模塊被實例化時,它需要一個 memory  對象。你可以創建一個新的WebAssembly.Memory并傳遞該對象。如果沒有創建 memory  對象,在模塊實例化的時候將會自動創建,并且傳遞給實例。

JS引擎創建一個ArrayBuffer來做這件事情。ArrayBuffer 是 JS 引用的 JavaScript 對象。JS  為你分配內存。你告訴它需要多少內存,它會創建一個對應大小的ArrayBuffer

ArrayBuffer 做了兩件事情,一件是做 WebAssembly 的內存,另外一件是做 JavaScript 的對象。

它使 JS 和 WebAssembly 之間傳遞內容更方便。

使內存管理更安全。

Table

WebAssembly.Table() 構造函數根據給定的大小和元素類型創建一個Table對象。

這是一個包裝了WebAssemble Table 的Javascript包裝對象,具有類數組結構,存儲了多個函數引用。在 JS  或者WebAssemble中創建Table 對象可以同時被JS 或WebAssemble 訪問和更改。

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

事例

為了演示,我將使用WebAssembly Studio應用程序將C文件編譯為.wasm。

我已經在wasm文件中創建了一個函數來計算一個數字的冪。我將必要的值傳遞給函數,然后用JavaScript接收輸出。

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

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"; }

應用

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

感謝各位的閱讀,以上就是“WebAssembly及其API的知識點總結”的內容了,經過本文的學習后,相信大家對WebAssembly及其API的知識點總結這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

青神县| 木兰县| 柘荣县| 澜沧| 门头沟区| 芷江| 滕州市| 赞皇县| 华阴市| 奉化市| 江安县| 襄垣县| 古蔺县| 涿州市| 襄城县| 望谟县| 县级市| 万全县| 南城县| 进贤县| 万载县| 新化县| 柘荣县| 晋州市| 门头沟区| 黄大仙区| 黔东| 揭阳市| 宜城市| 常州市| 乐亭县| 大方县| 民勤县| 桂阳县| 车致| 镇巴县| 肥西县| 井研县| 仪征市| 师宗县| 荃湾区|