我是靠谱客的博主 繁荣大叔,最近开发中收集的这篇文章主要介绍rust办宏G什么意思_WebAssembly + Rust + Vue + Webpack 初体验,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

309491e8fedf7d769d272c9da6f8f4bc.png

最近公司在做一个可视化的项目,由于数据量巨大的问题,看到网上说WebAssembly可以突破一些运行效率的瓶颈,记录一下捣鼓的过程和结果。也希望能给想在前端加入WebAssembly的同学抛砖引玉。

项目是自己搭建的vue+webpack,没有用vue-cli。

起手式

Rust环境安装

安装 Rust​www.rust-lang.org
c555ec522e71e0abe2bcf34e072592e9.png

wasm-pack安装,用来将rust编译成wasm文件。

编译 Rust 为 WebAssembly​developer.mozilla.org
d5739ac4135913ad503b4386f20398e4.png

Rust代码

use md5;
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn toMd5(param: &str) -> String {
    let digest = md5::compute(param); //将字符串转为Md5
    return format!("{:x}", digest); //返回转化后的String
}

wasm-pack打包后的文件

├── rust_wasm.d.ts
├── rust_wasm.js
├── rust_wasm_bg.js
├── rust_wasm_bg.wasm
└── rust_wasm_bg.wasm.d.ts

Vue引用wasm文件

将打包后的文件放到项目里,这里只用到了js文件,需要用ts的同学可以按需引用。并且额外添加了一个 index.js 文件,用作异步引入wasm的作用。

├── index.js
├── rust_wasm.js
├── rust_wasm_bg.js
└── rust_wasm_bg.wasm

index.js

export default import('./rust_wasm.js');

正式引用wasm,创建 test.js

import md5 from 'blueimp-md5';
import wasm from './wasm/index.js';

/**
 * 随机生成字符串
 * @param {number} e 字符串长度
 */
function randomString(e) {
    e = e || 32;
    var t = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678',
        a = t.length,
        n = '';
    for (let i = 0; i < e; i++) n += t.charAt(Math.floor(Math.random() * a));
    return n;
}

(async _ => {
    const module = await wasm;         //引入wasm对象
    const str = randomString(999999);  //生成999999位随机字符串

    //打印js生成的md5及所需时间
    console.time('js');
    console.log('%cjsMd5:' + md5(str), 'color:red');
    console.timeEnd('js');

    //打印wasm生成的md5及所需时间
    console.time('wasm');
    console.log('%cwasmMd5:' + module.toMd5(str), 'color:yellow');
    console.timeEnd('wasm');
})();

测试结果:

a3d2290c604a693fd4d6f9301a84f242.png

842a7ea5327a61b7c468437adbda6ce7.png

f074ca8469793b01eef794781ee45539.png

从结果可以看出来,在生成md5的效率上,wasm的效率是js的 6 - 8 倍。


在引入wasm中间遇到的坑:

WebAssembly module is included in initial chunk.
This is not allowed, because WebAssembly download and compilation must happen asynchronous.
Add an async splitpoint (i. e. import()) somewhere between your entrypoint and the WebAssembly module:

翻译了一下

WebAssembly模块包含在初始块中。
不允许这样做,因为WebAssembly的下载和编译必须异步进行。
在您的入口点和WebAssembly模块之间的某个位置添加异步拆分点(即import()):

大概意思就是不可以在初始化的时候就加载wasm文件,但是我在引入的时候确实是在index.js中import异步引入,找了许久,原来是在webpack打包的时候,需要配置下在打包js文件时候的路径,将引用wasm文件的路径添加到exclude属性中。

 module: {
      rules: [
            {
               test: /.js$/,
               exclude: [path.resolve('src/wasm')], // 你的wasm文件路径
               use: {
                    loader: 'babel-loader'
               }
            }
         ]
}

在测试中发现wasm在处理原始类型的数据,比如字符串或者数值类型的速度比较快,但是在测试数组或者对象的速度时,发现速度比不上原生的js。可能是我在序列化对象的时候消耗了比较大的时间。

如果有大佬有什么办法可以更快的处理js对象在rust中的运行速度,希望不吝赐教

extern crate serde_json;
use js_sys::Array;
use serde::{Deserialize, Serialize};
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
extern "C" {
    #[wasm_bindgen(js_namespace = console)]
    fn log(s: String);
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Node {
    data: NodeIndex,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct NodeIndex {
    index: i32,
}

#[wasm_bindgen]
pub fn test_arr(arr: &JsValue) -> JsValue {
    let mut elements: Vec<Node> = arr.into_serde().unwrap();
    elements.sort_by(|a, b| a.data.index.cmp(&b.data.index));
    let aa = JsValue::from_serde(&elements).unwrap();
    return aa;
}

#[wasm_bindgen]
pub fn test_sort(arr: Array) -> Array {
    arr.sort();
    return arr;
}

最后

以上就是繁荣大叔为你收集整理的rust办宏G什么意思_WebAssembly + Rust + Vue + Webpack 初体验的全部内容,希望文章能够帮你解决rust办宏G什么意思_WebAssembly + Rust + Vue + Webpack 初体验所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(39)

评论列表共有 0 条评论

立即
投稿
返回
顶部