我想比较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中获得更好的结果?