WebAssembly 运行速度比纯 JavaScript 函数慢很多

问题描述 投票:0回答:1

我刚刚接触 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++之间传递对象和数组??

javascript c++ webassembly emscripten embind
1个回答
0
投票

正如许多其他人指出的那样,您的 C++ 代码存在各种问题,这些问题会让您损失一些性能。如果你修复它们,你可能应该接近纯 JavaScript。

但是,如果您的主要目标是性能,那么您绝对无法从 WASM 中获得任何好处。在极少数情况下,WASM 实际上可以更快。您应该学习 V8 性能优化技术并坚持下去。

WASM 与性能无关。 WASM 是关于现有 C++ 软件到网络的兼容性和可移植性。

© www.soinside.com 2019 - 2024. All rights reserved.