在Node.Js中优化WASM模块,运行速度比JS慢

时间:2019-12-26 09:14:47

标签: javascript node.js rust webassembly wasm-bindgen

我想比较WASM(来自Rust)和Node.Js,所以我创建了一个非常简单的测试,使用最基本的冒泡排序算法对具有16个线程的100万个元素数组进行排序。两者都从 Node.Js版本v12.13.1 运行,结果看起来不太好

  

在13035ms内具有16个线程的1000000个元素的排序数组

     

在28245ms内具有16个线程和WASM的1000000个元素的排序数组

我想改进它们。

您可能会看到WASM模块比JS慢2倍。这是气泡排序的Rust代码

use wasm_bindgen::prelude::*;
use js_sys::Array;


#[wasm_bindgen]
pub fn bubble_sort(data: Vec<i32>)-> Array {
    let mut copy = data.to_vec();
    let mut temp: i32;
    for i in 0.. copy.len() {
        for j in 0.. copy.len(){
            if copy[j] > copy[i] {
                temp = copy[j];
                copy[j] = copy[i];
                copy[i] = temp;
            }
        }
    }
    let js_array : Array = Array::new();
    for i in 0..copy.len(){
        js_array.push(&wasm_bindgen::JsValue::from(copy[i]));
    }

    return js_array;
}

我在代码中看到的主要问题是我必须创建原始JS数组的两个副本,一个是因为WASM不允许您仅使用&mut,所以我无法更改原始数据,因此我必须更改并返回一个副本,第二次是因为WASM不允许您返回Vector,而是必须将它们转换为JS Array。 问题是我不知道如何解决此问题,我可以以某种方式跳过某些复制或以某种方式使它更快,更优化吗?

我还听说编译WASM模块时某些语言比其他语言慢,这增加了更多的开销,但是我找不到Node的速度。但是由于WASM基本上是为从JS导入而创建的,因此我怀疑Node的优化程度不足以使用WASM模块。

这是我从节点调用wasm-pack构建的方式(我注释掉了JS一个)

const { parentPort, workerData, isMainThread } = require("worker_threads");

//The Rust module
const {bubble_sort} = require("./pkg/bubble_sort_wasm.js")

/* Js Bubble Sort
function bubbleSort(arr){
        let temp;
        for (let i = 0; i < arr.length; i++) {
            for (let j = 0; j < arr.length; j++) {
                if(arr[j]>arr[i]){
                    temp = arr[j];
                    arr[j] = arr[i]
                    arr[i] = temp;
                }   
            }
        }
        return arr;
}
*/

if (!isMainThread) {

  //if(!workerData.withRust){
    //parentPort.postMessage(bubbleSort(workerData.arr));
  //}
  else{
    parentPort.postMessage(bubble_sort(workerData.arr));

  }
}

基本上我的问题是,有没有人知道如何/是否有可能对此进行优化,以便从Rust Bubble Sort中获得更好的结果?

0 个答案:

没有答案