日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

纵论WebAssembly,JS在性能逆境下召唤强援

發布時間:2023/12/13 综合教程 50 生活家
生活随笔 收集整理的這篇文章主要介紹了 纵论WebAssembly,JS在性能逆境下召唤强援 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

webassembly的作用

webassembly是一種底層的二進制數據格式和一套可以操作這種數據的JS接口的統稱。我們可以認為webassembly的范疇里包含兩部分

wasm: 一種體積小、加載快并且可以在Web瀏覽器端運行的底層二進制數據格式,并且可以由C++等語言轉化而來

webassembly的操作接口:例如WebAssembly.instantiate就可以將一份wasm文件編譯輸出為JS能夠直接調用的模塊對象

打破性能瓶頸
一直以來,我們都比較關心JS的運行速度問題,V8引擎解決了絕大多數情況下遇到的問題,但是少數情況下我們進行大量本地運算的時候,仍然可能遇到性能瓶頸,需要優化,這個時候webassembly的作用就凸現出來了

webassembly項目的編碼流程

性能無強關的部分用JS編寫

性能強相關的,并且需要大量本地運算的部分,先用C++/Rust編寫,通過命令行工具轉化為wasm代碼后讓JS調用

玄學的webassembly性能提升

webassembly相對于純JS的性能提升是隨具體場景和條件的變化而變化的

當您使用WebAssembly時,不要總是期望得到20倍的加速。您可能只得到2倍的加速或者20%的加速。或者,如果您在內存中加載非常大的文件時,或者需要在WebAssembly和JavaScript之間進行大量通信時,那么速度可能會變慢。 作者:Robert 《Level Up With WebAssembly》一書的作者,同時也是一位生物信息學軟件工程師

參考鏈接

在上面的文章的作者Robert,做了這樣一個實驗,他使用 seqtk,一個用C編寫的評估DNA測序數據質量(通常用于操作這些數據文件)的軟件,去對比webassembly相對于普通JS帶來的性能提升

一.Robert的對比測試結果
下面是他的測試結果

第一步:運行序列分析軟件seqtk,對比性能:9倍提升

第二步:刪除不必要的printf輸出,對比性能:13倍提升

第三步:去除函數的重復調用后,對比性能:21倍提升

當然,上面的概括也許太過簡略,大家可以看看Robert的原文以得到更為詳細的認識

二.運行Fibonacci函數的性能對比
有位博主,對比了運行遞歸無優化的Fibonacci函數的時候,WebAssembly版本和原生JavaScript版本的性能差距,下圖是這兩個函數在值是45、48、50的時候的性能對比。

文章鏈接作者:detectiveHLH

三.IVweb的的性能對比測試
IVWeb團隊對長度不同的文本進行加密處理,對比webassembly相對于純JS的性能提升,結果發現

對于長文本(2M文本) 的密集計算,webassembly的性能提升很大

對于短文本("IVWEB")的密集計算,webassembly和純JS性能相差無幾

第一組測試:2M長文本100000 次加密處理

第二組測試:"ivweb"短字符加密100000 次

資料來源

從上面的資料中我們了解到,webassembly性能提升的確存在,但是這個提升的范圍是隨條件和場景而變化的,需要遵循一定的原則

webassembly的兼容

下面是我在can i use上查到的結果,可以看到在現代瀏覽器上兼容良好,覆蓋率達到88%。主要的問題在于IE瀏覽器不支持(IE11)

IE兼容解決方案
Internet Explorer 11 是最后一個占有很大的市場份額,但不支持wasm的瀏覽器。我們可以通過 binaryen 項目的 wasm2js 工具,將我們的 WebAssembly 編譯成 JavaScript,就可以獲得 IE11 的大部分支持了

實戰 WebAssembly

在瀏覽器中使用WebAssembly主要有兩種方式:

編寫Rust代碼,然后通過wasm-pack轉化成wasm代碼

編寫C/C++代碼,然后通過Emscripten轉化成wasm代碼

備注:Rust是一門高性能的系統編程語言

通過Rust接入WebAssembly

《Rust 和 WebAssembly 用例》

1.安裝rustup,初始化Rust環境,它會順帶安裝cargo等工具(相當于前端的Node安裝)

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

2.安裝編譯工具wasm-pack(相當于前端的babel)

cargo install wasm-pack

3.創建一個文件夾,進入后運行下面代碼,初始化一個Rust 項目

cargo new --lib hello-wasm

初始化的文件夾如下所示

4.修改lib.rs,改為以下幾段Rust代碼,這段代碼的is_odd是一個判斷數字是否為奇數的方法

extern crate wasm_bindgen;

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn is_odd(n: u32) -> bool {
    n % 2 == 1
}

5.修改配置文件Cargo.toml

這個文件和我們的package.json有點像,我們就依樣畫葫蘆,這個文件大概要寫成下面這個樣子

[package]
name = "hello-wasm"
version = "0.1.0"
authors = ["作者名"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
crate-type = ["cdylib"]

[dependencies]
wasm-bindgen = "0.2"

備注

dependencies中必須要有wasm-bindgen這個依賴

同時還要指定crate-type = ["cdylib"],否則轉化不能成功

6.運行以下命令進行編譯轉化

wasm-pack build --scope [自己的名字]
// My Example
wasm-pack build --scope penghuwan

編譯開始

編譯成功后,新增了pkg文件夾和target文件夾


讓我們看看pkg文件夾下的文件有哪


7. 將包發布到npm

1.cd pkg 
2.npm publish --access=public

8.安裝剛剛發布的wasm模塊,并通過webpack工具加載后,在瀏覽器運行以下代碼

const js = require("hello-wasm");
js.then(js => {
 const num1 = js.is_odd(3);
 const num2 = js.is_odd(4);
  console.log(num1);
  console.log(num2);
});

9.瀏覽器輸出

通過C/C++接入WebAssembly

1.首先要按照文檔下載編譯工具emscripten

https://emscripten.org/docs/getting_started/Tutorial.html

備注:如果沒有將source ./emsdk_env.sh寫入到啟動文件中的話,那么每次使用前都要在給定目錄下運行一遍

2.創建一個文件h.c,寫入以下代碼

#include <stdio.h>

int main(int argc, char ** argv) {
 printf("Hello World");
}

3.用命令行編譯它

emcc h.c -s WASM=1 -o h.js

生成文件如下圖所示


4.運行生成的h.js,則可看到輸出了Hello World

WebAssembly相關的接口 API

看了上面的案例,你可能會覺得有些奇怪:怎么我們沒有涉及瀏覽器提供的webassembly的API呀?
其實是有的,只不過在工具編譯的時候自動幫忙填寫了一些API而已,我們看下上面從h.c編譯出來的h.js的一些片段就知道了

下面我們就來介紹下怎么手動去寫這些API

接口
>> WebAssembly.Instance
實例包含所有的 WebAssembly 導出函數 ,允許從JavaScript 調用 WebAssembly 代碼.

對象屬性

exports屬性: 一個對象,該對象包含從WebAssembly模塊實例導出的所有函數屬性

>> WebAssembly.Module
包含已經由瀏覽器編譯的無狀態 WebAssembly 代碼,可以高效地與 Workers 共享、緩存在 IndexedDB 中,和多次實例化。

對象屬性

exports屬性:一個數組,內容是所有已聲明的接口的描述。

imports屬性和:一個數組,內容是所有已聲明的引用的描述。

參考鏈接

方法
>> WebAssembly.instantiate
它是編譯和實例化 WebAssembly 代碼的主要方法

參數:包含你想編譯的wasm模塊二進制代碼的ArrayBuffer的類型實例

返回值: 一個Promise, resolve后的值如下所示

{
  module: 一個被編譯好的 WebAssembly.Module 對象. 
  instance: 一個WebAssembly.Instance對象
}

Example

fetch('simple.wasm').then(response =>
  response.arrayBuffer()
).then(bytes =>
  WebAssembly.instantiate(bytes)
).then(result =>
  result.instance.exports // exports是wasm中輸出的
);

webassembly的未來展望

多線程

SIMD(單指令流多數據流)

64位尋址

流式編譯(在下載的同時編譯 WebAssembly 文件)

分層編譯器

隱式 HTTP 緩存

參考文章

webassembly的使用場景及其限制

之前我們已經說到,webassembly適用于JS難以解決的大計算量的應用場景,如圖像/視頻編輯、計算機視覺,3D游戲等等。在這些場景下,webassembly能夠大限度地提高速度,彌補JS的缺陷和硬傷。

同時在另一方面,我們也需要認識到以下幾點:

其實在大多數場景下我們都不需要用到webassembly。因為V8等JS引擎的優化帶來了巨大的性能提升,已經足夠讓JS應對絕大多數的普通場景了,所以只有在以上的少數場景下,我們才需要做這種“二次提升”

和很多其他特性一樣,兼容性同樣是webassembly的一道坎,現代瀏覽器雖然支持度良好,但是在國內IE泛濫的特殊情況下, 這仍然是對webassembly的一個挑戰。不過在桌面應用上或者一些對兼容性要求較低的工具型網頁運用上,webassembly已經生根發芽,甚至能夠遍地開花。

webassembly的產品案例

設計工具Figma
一般情況下,為了使用速度,設計工具都會選擇Adobe等本地應用,而不會選擇瀏覽器網頁應用,而能夠同時打開十幾個畫板也沒有卡頓的Figma正在嘗試改變這一認知,webassembly讓它具有高效流暢的體驗


白鷺游戲引擎
白鷺游戲引擎是一套HTML5游戲開發解決方案,它衍生了開發莽荒紀同名手游、夢道、坦克風云的等游戲,而利用 WebAssembly,白鷺引擎讓游戲運行性能提升了300%。


OpenGL 圖形引擎Magnum
Magnum 是一款數據可視化 OpenGL 圖形處理引擎,也采用了WebAssembly支撐瀏覽器環境的應用

參考資料

from:https://www.cnblogs.com/penghuwan/p/11982601.html

總結

以上是生活随笔為你收集整理的纵论WebAssembly,JS在性能逆境下召唤强援的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。