WebAssembly是一种新的编码方式,可以在现代的网络浏览器中运行 - 它是一种低级的类汇编语言,具有紧凑的二进制格式,可以接近原生的性能运行,并为诸如C / C ++等语言提供一个编译目标,以便它们可以在Web上运行。它也被设计为可以与JavaScript共存,允许两者一起工作。
在进一步介绍之前,以下是我认为WebAssembly在可预见的未来不会发生的几件事情:
1、替换JavaScript。
2、一站式应用商店,为现有的web应用程序充电。
3、完全替代本机应用程序。
很多程序员都知道WebAssembly很快,那它到底有多快呢?
image.png作为参考,每秒60帧(FPS)是大多数显示器允许的最大值,并且平均帧时间为16.6MS。运行60 FPS就足以提供一个平滑顺畅的用户体验。电影和电视通常是24 FPS,这需要大约42 MS的平均帧时间。任何小于10 FPS的动画都是不可接受的,条形是每帧100 MS。
用WASM进行开发
WASM工具非常新,C ++和Rust是迄今为止所看到的唯一两个支持的语言。
构建工具
虽然工具很新但很好用,只是最初设置Emscripten编译器阶段有一点困难,程序员可使用与标准GCC编译非常相似的命令编译WASM命令。为了简化测试,可以使用这些工具:Clang,LLVM和Binaryen。
Javascript API和C ++通信
WASM文件用于生成WebAssembly模块(将其视为可执行文件),然后将其实例化(将其视为流程)。这个实例是沙箱,可以从JavaScript代码中直接访问。创建WASM模块非常简单,尤其是ES6 Promises从网络中获取二进制代码,通过一个非常简单的命令就可以运行它,并且bam!模块。
实例化模块是提供WASM内存对象和JavaScript导出的函数,这可能包括C ++标准库中的大量内部功能。数学函数(如sin和cos)通常使用原始组件段实现,不能直接在WASM中使用。
一旦模块被实例化,从C ++代码导出的所有函数都可以附加到实例的“exports”对象中使用。 一般来说,这些都是C ++代码中的功能,所以建议使用extern“C”,以防止由C ++编译器执行的名称被修改。
就像其他工具一样,WASM并不是适合于所有场景。在决定是否在项目中使用它之前,需要先了解一些事情:
WebAssembly只能用于数字通信
WebAssembly支持32位和64位的整数和浮点数,C ++结构可以很好地使用数字类型(所有数据最终都是字节),但JavaScript对象和数组不是很容易转换,必须投入相当数量的逻辑来将JavaScript对象转换为等效的C ++对象。
这里是将对象从WASM转换为JS,反之会导致性能和代码复杂性方面的成本。在WebAssembly中编写不同的模块,而不仅仅是单个类或函数实现。
JavaScript负责所有内存管理
WebAssembly必须使用由JavaScript提供的内存堆。从JavaScript的角度看,这实际上是一个ArrayBuffer包装器。从C ++的角度看,这看起来像一个指针的正常heap-de引用。这意味着你可以编写解引用NULL的有效代码,0x00是一个JS ArrayBuffer开头的有效地址,但不要每次都这么做。
通过JS ArrayBuffer访问WASM实例内存是很好的,因为它允许程序员从应用程序的JS和WASM两面访问内存。不幸的是,无法访问系统分配命令,如“malloc”和“free”,因此本质上必须自己编写,使用Emscripten等工具可以帮助缓解这种痛苦,因为它有很多可以重复使用的样板。
调试
WebAssembly的文本和二进制格式是可互换的,因此浏览器可以显示代码的文本格式。 然而,该功能不如听起来好用,因为WAST(WebAssembly Text格式)似乎是装配和LISP的不合理组合。我建议为可以从C ++环境运行的模块设置单元测试。这样,可以更好地访问控制台日志调试或正确的IDE调试工具。
请记住,Javascript也很快
对很多人来说,WebAssembly更像是加速版JavaScript,但其实JavaScript也很快。JS程序员可以通过合理的优化配置代码,解决性能瓶颈。用for循环代替每个调用,避免在可能的情况下重新分配内存,不要对垃圾回收器施加压力,确保代码与现代JavaScript引擎中的优化编译器兼容。
那么,程序员应该使用WebAssembly吗?
当然,任何Web程序员都可以从学习WebAssembly中获益。对于JavaScript和C ++程序员来说,学习曲线也相当温和。虽然它有很多新功能,但要记住,WebAssembly适合于在WASM中编写一个模块,而不仅仅是类。在运行WASM和运行JS之间有明确的界限,尽可能少的进行非数字通信。
网友评论