WebAssembly 数组传递(输出篇)

最近有一个项目需要以原生方式输出js数组,这里分类一些方法:

公共头部:

#include 
#include 

using namespace emscripten;

*注意:在使用emscripten::val和emscripten::bind时,编译时要带上--bind参数

耗时对比:

(以传输1,580,000个double数据为例,数据单位:毫秒)

方法1:

查阅文档可知,val就是代表的js里的原生数据类型。

通过val::array()就能构造数组,通过.set方法可以设置数据内容

所以最初始的办法就是直接使用for循环复制 

val get1XArray(double *arr, int len){
    val ret = val::array();
    for(int i = 0; i < len; i ++) ret.set(i, arr[i]);
	return ret;
}

优点:简单、直观、可扩展

缺点:内存中不连续造成寻址时间长

 

方法2:

上面这种方法由于数组长度不固定,造成了内存浪费,解决方法就是使用TypedArray(对应double的是Float64Array)

查阅文档可知,通过val::global能取得js全局对象,.new_方法新建实例

改写后:

val get1XArray(double *arr, int len){
    val ret = val::global("Float64Array").new_(len); //js: new Float64Array(len)
    for(int i = 0; i < len; i ++) ret.set(i, arr[i]);
	return ret;
}

但是这样速度反而更慢了,可能是因为new操作很耗时

好处是内存利用率提高了

方法3:

之后在想办法解决速度问题时,发现了文档的实例里有一个typed_memory_view(length, array)函数

(吐槽一下,文档里没找到这个函数的解释,官方文档不认真啊)

所以最终改写版:

val get1XArray(double *arr, int len){
	return val(typed_memory_view(len, arr));
}

优点:速度上的飞跃,原先需要1200ms才能转换的数据,现在大概只要7ms

缺点:输出类型为对应的TypedArray,需要动态长度数组的不能用。且指针要在js操作完成后才能释放。

传输二维数组的方法:

val get2XArray(double **arr, int y_len, int x_len){
	val ret = val::array();
	for(int i = 0; i < y_len; i ++){
		ret.set(i, val(typed_memory_view(x_len, arr[i])));
	}
	return ret;
}

另:

因为目前还没有wasm的群,所以自己建了个:866749590

有问题可以相互帮助

你可能感兴趣的:(WebAssembly)