用js的方式運行c程序之webassemly

在這裏就不科普webassemly的做用以及好處了,請自行百度。html

那麼,怎麼經過js的方式在瀏覽器中運行c程序呢,其中原理以下:git

可能另外一張圖會更詳細:github

1.安裝emscriptenweb

說明文檔地址:https://emscripten.org/docs/getting_started/downloads.html瀏覽器

如下步驟爲macOs下命令:async

step1:克隆項目------------git clone https://github.com/emscripten-core/emsdk.git函數

step2:進入項目目錄--------cd emsdk工具

step3:安裝最新emsdk工具---./emsdk install latest性能

step4:激活---------------./emsdk activate latestfetch

step5:執行批處理添加環境變量source ./emsdk_env.sh

已經安裝好了,看一下版本:

2.寫一個c文件(test.c)並轉換.wasm

#include <emscripten/emscripten.h>

int EMSCRIPTEN_KEEPALIVE add(int a, int b) {
   return a + b;
}

int EMSCRIPTEN_KEEPALIVE fibonacci(int n) {
    if (n <= 1) {
        return n;
    } else {
        return fibonacci(n - 1) + fibonacci(n - 2);
    }
}

注意,紅字必須,這是相比常規c文件不一樣的地方。

轉換命令:

emcc test.c -Os -s WASM=1 -s SIDE_MODULE=1 -o test.wasm

而後你就在相同目錄下獲得了一個test.wasm文件。

3.經過js引入.wasm並執行其中函數

這裏我封裝了一個引入.wasm文件的工具函數,代碼以下:

const importObj = {
    global: {},
    env: {
        'memory': new WebAssembly.Memory({initial: 256, maximum: 256}),
        '__memory_base': 0,
        'tableBase': 0,
        'table': new WebAssembly.Table({initial: 10, element: 'anyfunc'}),
        abort:alert
    }
};
 
export async function addModule(url,callback){
    fetch(url).then(response =>
        response.arrayBuffer()
    ).then(bytes => WebAssembly.instantiate(bytes,importObj)).then(results => {
        var instance = results.instance;
        var module = instance.exports;
        callback(module);
    });
}

index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>WebAssemblyLearning</title>
</head>
<body>
    
</body>

<script type="module">
    import {addModule} from './utils/wasm.js';
    var num = 42;
    function getDuring(func,type){
        const start = Date.now();
        func(num);
        console.log(type +'執行斐波那契數列消耗時間:' +(Date.now() - start) + 'ms\n');
    };
    addModule('./add.wasm',function(module){
        getDuring(module._fibonacci,'C程序');
    });
    function fibonacci(n) {
        if (n <= 1) {
            return n;
        } else {
            return fibonacci(n - 1) + fibonacci(n - 2);
        };
    };
    console.error('遞歸次數:'+ num);
    getDuring(fibonacci,'JavaScript')
</script>

</html>

咱們看到,上面經過兩種不一樣的方式執行了一個遞歸次數爲42的斐波那契數列求和函數,對比一下二者的性能:

因此對於追求性能的web程序來講,webassemly將是一個很好的選擇。

相關文章
相關標籤/搜索