WebAssembly 数组传递(输出篇)

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

公共头部:

#include <emscripten/val.h>
#include <emscripten/bind.h>

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

有问题可以相互帮助

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值