我刚刚接触 WebAssembly。我只是尝试编写一个函数来根据某些条件过滤对象数组并返回一个 id 数组。我运行这个函数并测量执行时间。令人惊讶的是,WebAssembly 的运行速度比 JS 慢 10 倍。
我的过滤器JS功能:
function filter(array: Obj[], criteria: Filter, additionalArr: number[]){
//Filter....
}
C++ 文件如下:
#include<emscripten/bind.h>
#include<emscripten/val.h>
struct Filter {
vector<int> f1;
vector<int> f2;
vector<string> f3;
Filter(): f1({}), f2({}), f3({}) {}
Filter(vector<int> f1, vector<int> f2, vector<string> f3) :
f1(f1), f2(f2), f3(f3) {}
};
struct Obj {
int p1;
int p2;
string p3;
Obj (): p1(0), p2(0), p3("") {}
Obj (int p1, int p2, string p3) :
p1(p1), p2(p2), f3(p3) {}
}
Obj processObj(emscripten::val jsObj){
Obj wasmObj = new Obj();
wasmObj.p1 = jsObj["p1"].as<int>();
wasmObj.p2 = jsObj["p2"].as<int>();
wasmObj.p3 = jsObj["p3"].as<string>();
return wasmObj;
}
Filter processFilter(emscripten::val jsFilter){
//Similar to processObj
}
bool filterOneObj(Obj obj, Filter criterias, vector<int> additionalArr) {
//Filter one obj base on criterias and additionalArr
}
emscripten::val wasmFilter(emscripten::val objJS, emscripten::val criteriaJS, emscripten:: val additionalArrJS) {
vector<int> result;
Filter wasmFilter = processFilter(criteriaJS);
for(size_t i = 0; i < objJS["length"].as<size_t>(); i++) {
if(filterOneObj()) result.push_back(objJS[i]["p1"].as<int>());
}
return val::array(result);
}
EMSCRIPTEN_BINDINGS(module) {
class_<Filter>("WasmFilter")
.constructor<vector<int>,
vector<int>,
vector<string>>
.property("f1", &Filter::f1)
.property("f2", &Filter::f2)
.property("f3", &Filter::f3)
class_<Obj>("WasmObj")...//similar to Filter
emscripten::register_vector<int>("IntList");
emscripten::register_vector<Obj>("ObjList");
emscripten::function("wasmFilter", &wasmFilter);
}
使用以下命令将 C++ 编译为 wasm:
emcc -lembind -Iinclude -s WASM= -s EXPORT_ES6=1 -s MODULARIZE=1 -s ENVIRONMENT=web filter.cpp -o filter.js
我用大数组(100.000)运行这个函数,结果是 JS 执行时间约为 1 秒,从 JS 调用 wasmFilter 约为 10 秒。 我不知道 c++ 文件中的哪一部分使 wasm 运行缓慢。是因为使用了
embind
吗???
我读了很多文章,表明 WebAssembly 比 Js 更快。 我也知道在某些情况下WebAssembly效率不高。但就我而言,WebAssembly 运行速度很慢。 为什么?有没有什么有效的方法可以在JS和C++之间传递对象和数组??
正如许多其他人指出的那样,您的 C++ 代码存在各种问题,这些问题会让您损失一些性能。如果你修复它们,你可能应该接近纯 JavaScript。
但是,如果您的主要目标是性能,那么您绝对无法从 WASM 中获得任何好处。在极少数情况下,WASM 实际上可以更快。您应该学习 V8 性能优化技术并坚持下去。
WASM 与性能无关。 WASM 是关于现有 C++ 软件到网络的兼容性和可移植性。