WebAssembly学习笔记

WebAssembly是最近十年 web 技术发展中最重大的一个新技术。不少人可能都据说过它最重要的一个特性:性能好,运行快。那WebAssembly到底是什么?是什么使得它性能好运行快的呢?web

WebAssembly是什么?

WebAssembly 是一种能把除了JavaScript之外的编程语言编写的代码通过编译器编译转换为能在现代浏览器中运行的代码的技术。众所周知,JavaScript在 Web 中的地位一直独步天下,无 yan 能敌,因此WebAssembly所指的性能优点,是针对 JavaScript 而言的。WebAssembly并非为了替代 JavaScript 出现的,而是但愿与 JavaScript 并驾齐驱共同开发出性能更高的应用。编程

首先看看 JavaScript 的性能历史

JavaScript诞生于1995年,目的是为了给浏览器 HTML 网页增长动态交互功能,并无考虑太多性能问题,事实证实在前十年里浏览器也不须要它有多快。一切变化发生在2005年,谷歌在多款交互应用中使用Ajax技术让交互体验获得了极大的提高,让人们认识到了原来网页能作的事情远远不是内容的展现和表单的提交。浏览器

到2008年,JavaScript在浏览器中低下的执行效率,已经成为限制程序猿们在网页施展拳脚的一大阻碍。忽然,有个叫谷歌的厂商推出了一款叫Chrome的浏览器,它与以往浏览器最大的不一样在于内置了一个 JITs(just-in-time compilers),一个能在 js 代码执行时根据某些模式动态编译代码为能在浏览器中更高效执行的代码的技术,详细介绍能够看这篇文章: a crash course in just in time(jit) compilers。今后拉开了浏览器性能大战的序幕。服务器

js performanc

时间再推动10年到2018年,此时JavaScript的使用场景已经远远超过了原先的想象:服务端、网页游戏、WebVR/AR、图片/视频处理等等场景,JITs 都已经不能知足这些对性能日益严苛的场景了,此时咱们须要更进一步的突破,这个就是 WebAssembly网络

为何WebAssembly更快?

就如第一部分所提,WebAssembly的性能优点是针对 JavaScript 而言的,下面咱们分别从 JavaScript 和 WebAssembly 的执行过程一一对比优点到底在哪:编程语言

js-wb-excute

获取

因为 WebAssembly 是由编译器生产出来的,而且将被浏览器直接解析执行,能够节省那些为了给人类阅读而添加的没必要要代码,从而能够作到文件大小甚至比通过压缩的 JS 代码更小。因此在相同的网络状况下,从服务器获取一个 WB 文件会比获取一个 JS 文件 更快。函数

解析

当 JS 文件成功到达浏览器以后,浏览器会将其解析成一棵抽象语法树(Abstract Syntax Tree)(可是只会先解析当前须要执行的那部分代码,而其他未执行的函数将会保存成存根),而后再转换为 JS 引擎识别的 IR(intermediate representation) 层字节码(认识 JAVA 的应该对这个词不陌生)。性能

反过来咱们看 WebAssembly 自己已是通过高级语言编译出来的 IR 层代码了,不须要在浏览器端进行解析而只须要把通过压缩的内容解码出来,节省了至关多的时间。优化

编译和优化

这个阶段是 JITs 负责作的事情,不一样浏览器对 WebAssembly 的处理可能会有细微差异,咱们以都使用 JITs 进行优化的场景来看看为什么 WebAssembly 会比 JavaScript 更快,有如下三点: (阅读下面内容须要先对 JIT 有必定认识,不清楚的能够先看 这里编码

  1. 因为 WebAssembly 的输入类型是固定的(byte),因此不须要经过运行代码这种方式去检查输入类型来进行编译优化
  2. 在 JavaScript 中相同一段代码可能由于输入值不一样须要分别编译成不一样的版本,而 WebAssembly 也不须要进行这种冗余的操做,缘由如上; 三、 WebAssembly 在从高级语言(C/C++/Rust)编译而来的时候,已经通过编译器优化一次了,因此在 JITs 中须要作的事情更少;

重优化

仍是因为 JavaScript 动态类型的缘由,一段通过了深度优化的代码,可能由于此次执行的时候输入值类型变了,致使 JITs 须要根据输入值类型从新进行一次上一步的优化工做,这也须要花费必定的时间。

而 WebAssembly 输入值固定,JITs 不须要在每次代码执行时去计算输入值的类型,从而不会发生重优化这样的事情。

执行

JavaScript 代码通常是人写的,而 WebAssembly 是由编译器编译出来的,是直接针对机器产生的代码,会包含更多对机器性能优异的指令(instructions),这部分差别针对不一样的功能代码 WebAssembly 可能会比 JavaScript 快 10%~800%

垃圾回收

咱们都知道在 JavaScript 中没必要人工去执行变量的释放和内存的回收,由于 JS 引擎有自动垃圾回收功能,能自行判断该回收什么东西甚至足够智能知道在什么时候进行回收操做。可是这仍是存在天花板可能会影响代码的执行。

在目前为止,WebAssembly 都不支持自动垃圾回收,内存由代码手动管理(因为使用了 C/C++编写),这将会加大开发者编码的难度,但能保证代码性能更可控。

总结

总的来讲,大多数场景下 WebAssembly 比 JavaScript 性能更好是由于:

  1. WebAssembly 代码更小的体积;
  2. 解码 WebAssembly 比解析转译 JavaScript 用的时间更少;
  3. 优化 WebAssembly 的用时比优化 JavaScript 的更短,由于前者是已经通过一次编译优化而且面向机器的代码;
  4. WebAssembly 没有重优化这个过程;
  5. WebAssembly 包含对机器更友好的指令;
  6. JavaScript 没法人为控制垃圾回收,而 WebAssembly 能够有效控制内存回收的时机;

=============

本文主要知识和灵感来源于:

  1. A cartoon intro to WebAssembly系列文章,感谢做者。后续本博客会翻译几篇此做者编写的 WebAssembly 使用教程。
  2. WebAssembly Concepts
  3. WebAssembly format

版权声明:原创文章,如需转载,请注明出处“本文首发于xlaoyu.info

相关文章
相关标签/搜索