WebAssembly字节码是什么?速度远超JavaScript(JS)的一门技术

一、webassembly是什么?
webassembly是针对web设计的一种低级语言,这种可移植的二进制格式旨在提高web应用的运行速度。这种语言的设计初衷是获得比javascript(js)更快的解析速度(最高提高20倍)和执行速度。
webassembly的出现是要解决这些问题:
javascript:性能不够理想,以及语言本身的一堆坑(这个大家都懂)flash:私有技术(而且漏洞一堆),并且是纯二进制格式silverlight:私有技术,并且是纯二进制格式各种插件(plug-in):安全性问题,平台兼容问题
二、webassembly的公布时间
webassembly社区小组于2015年4月成立,其使命是“为web设计一种全新的、可移植的、能够高效加载及易于编辑的轻量级格式,以促进跨浏览器协作”。
三、从何处入手
首先你必须使用binaryen设置emscripten sdk,将c/c++代码或rust代码转化为wa的“.wasm”二进制文件,或者使用与lisp类似的s-表达式将代码转化为“.wast”(或“.wat”)文本格式,如图1所示。
图1. 从源代码到web的处理过程
你可以从这个在线工具开始学习,快速查看代码片段。
在页面右侧的反汇编输出中,你可以看到头两行代码如下所示:
1
2
0000000:?0061?736d;?wasm_binary_magic
0000004:?0b00?0000;?wasm_binary_version
第一行与魔术数字“0x6d736100”有关,这个数字代表的是“\0asm”。第二行显示的是版本号,这里版本号为“0xb”。由于当前wa的版本号是0xd,因此这个在线工具生成的字节码不能用于当前版本的web浏览器,不过这段代码还是值得一看的。当webassembly最终发布时,其版本号会被设定为0x1。
四、webassembly如何工作
目前webassembly需要通过javascript加载和编译。主要包括以下四个步骤:
1、加载wasm字节码。
2、将wasm字节码编译为模块。
3、实例化模块。
4、运行函数。
翻译过来就是:
1
2
3
fetch('your_code.wasm').then(response?=>?response.arraybuffer()
).then(bytes?=>?webassembly.instantiate(bytes,?{})
).then(instance?=>?instance.exports.your_exported_function?()
从上述代码可知,“webassembly.instantiate”可以同时用于编译和实例化模块。
五、webassembly的使用场景
作为asm.js的下一代改进版,webassembly使用了javascript中一个非常受限的指令子集,该子集最适合作为c编译器的编译目标。webassembly不包含javascript对象,也不直接访问文档对象模型(document object model,dom)。从本质上来讲,webassembly只允许对类型数组进行算术运算和操作。
一些初步样例表明,使用wasm实现的斐波那契数生成算法比对应的js实现性能上更优,有超过350%的性能提升。
目前,webassembly只是在简单模仿js的功能,但人们计划扩展webassembly的使用场景,以处理js中难以处理的事情,同时不增加语言的复杂度。比如,人们计划使webassembly默认支持simd(single instruction,multiple data,单指令流多数据流)、线程、共享内存等等功能。
许多流行视频游戏编辑器已经准备就绪,开始将webassembly技术与webgl 2.0相结合,将部分3d功能引擎移植到这个全新平台上。你可以试一下epic出品的zen garden,体验这种全新技术。
六、这是否就是javascript的末日
webassembly会促进javascript的发展,而不是导致其灭亡,它可以为web中的关键功能带来语言上的多样性并提高性能。webassembly不单单给js带来性能上的提升,同时也造福了web浏览器。
可以预想的是,五年后,我们使用js的方式将大大不同。目前,我们在很多场景中都难以使用js代码完成任务,大部分功能都需要借助复杂库来实现。
由于webassembly的易用性和简单性,我们预测会有越来越多的代码从c++或python转化为js,甚至直接转化为webassembly。这意味着你不需要去学习一门全新的语言。js虚拟机还是会存在,但对应工具会不断发展,以获取更优的性能。
七、webassembly与基于ms activex/adobe flash/orcale java applet/ms silverlight/google nacl构建的富因特网应用之间有何区别
由于不同的公司各自推出了不同的标准,因此富因特网应用(rich internet application, ria)无法形成标准的开放格式。
比如,微软在自家的ie浏览器中推广activex技术。该技术让开发者能够通过com组件将打包功能重新集成到web页面中。
google推出了native client,让开发者将一些c/c++代码打包集成到浏览器中,然而,只有chrome支持这项技术,达不到广义上的可移植要求。
几年前,mozilla发布了asm.js,打开了性能优化的大门。他们最早提出了使用js中的严格子集。通过限制语言的功能性,他们能够预测虚拟机的下一步反应,从而通过移除某些不必要的检查操作以提高性能。但这种技术也会影响语言的动态行为。
所有的这些技术构成了今天wa诞生的基础。webassembly运行在js虚拟机内部,使用了js的部分功能,这意味着它不仅能够与运行最新web浏览器的设备兼容,也能做到向前兼容。为了实现这一点,设计人员正在开发一个polyfill,核心思想是将每个函数转换为语义上等效的js代码,虽然这样做会影响运行性能,但至少能解决代码的运行问题。
八、webassembly长什么样
顾名思义,webassembly的最终形式是一种低级字节码,可以转换为汇编代码,但与通常的cpu汇编代码不同。
我们来看看“hello world”这个例子(值得一提的是,虽然“hello world”是大多数程序员相当熟悉的一个程序,但这个程序并不是特别适合这门语言,因为wa默认情况下没有集成打印功能,这也是为什么以下代码必须通过js从标准库中导入该功能,然后传递所需的参数)。
size_t fwrite(const void *ptr, size_t size, size_t nmemb, file *stream)这个c语言库函数可以从ptr指向的数组中读取数据,并将数据写入到stream文件流中。
紧跟在wasp代码之后的是wasm字节码的版本号,如上文所述。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
;;?webassembly?wasm?ast?hello?world!?program
(module
(memory?1?
(segment?8?hello?world!\n)
)
(import?$__fwrite?env?_fwrite?(param?i32?i32?i32?i32)?(result?i32))
(import?$_get__stdout?env?get__stdout?(param)?(result?i32))
(export?main?$main)
(func?$main?(result?i32)
(local?$stdout?i32)
(set_local?$stdout?(call_import?$_get__stdout))
(return?(call_import?$__fwrite
(i32.const?8);;?void?*ptr=>?address?of?our?string
(i32.const?1);;?size_t?size=>?data?size
(i32.const?13)?;;?size_t?nmemb?=>?length?of?our?string
(get_local?$stdout));;?stream
)
)
)
代码1:wast版的hello world程序(参考自github)
上一个:企业网站应该怎么做?如何让用户喜欢?
下一个:企业网站的重要性
汶上网站建设,汶上做网站,汶上网站设计