WebAssembly

2019/04/27

215

WebAssembly

什么是 Assembly

经过编译器编译所得到的,供 CLR 进一步编译执行的中间产物,在 Windows 系统中,它一般表现为 .dll 或者是 .exe 格式,它跟普通意义上的 Win32 可执行程序是完全不同的,程序集必须依靠 CLR 才能顺利执行。

CLR (Common Language Runtime) 公共语言运行时,它定义了一套代码可执行环境,可执行一种称为通用中间语言的字节码

CLR

什么是 WebAssembly

WebAssembly 运行在客户端浏览器上,旨在提供比 JavaScript 更快的执行速度。WebAssembly 允许开发者使用自己熟悉的编程语言进行开发,Google Chrome、Mozilla Firefox、Microsoft Edge、Apple Safari 于2017年11月都开始实验性支持 WebAssembly。

WebAssembly 并不是一门编程语言,而是一份字节码标准,需要用高级编程语言编译出字节码放到 WebAssembly 虚拟机中才能运行, 浏览器厂商需要做的就是根据 WebAssembly 规范实现虚拟机。

Ending定律也称终结者定律:出现在2016年 Emscripten 技术交流会上,它断言所有可以用 WebAssembly 实现的终将会用 WebAssembly 实现。

从此 Web 走上了改革开放的道路。

Web 的历史

1995年5月,网景公司做出决策,未来的网页脚本语言必须看上去于 Java 足够相似,但是比 Java 简单,使得非专业网页作者也能很快上手。后来这个脚本语言被命名为“JavaScript”,它交由 Brendan Eich 设计,但是作者对 Java 一点兴趣也没有,他更喜欢函数式编程,为了应付公司交给他的任务,他只花费了10天时间就把 JavaScript 设计出来了。

布兰德·艾克

由于设计周期太短,所以无法避免的造成了一些坑,没有泛型、缺省参数、操作符重载、异常(后期追加上的)等。作者没有想到多年以后,JavaScript会如此火爆,所以有些设计上的缺陷从小水洼变成大水坑,之后很长时间 JS 的发展史都可以说是填坑史,JS 现在也越来越好了。

以今天的视角看待 JavaScript 已经变成最流行的编程语言,我们可以说,是因为Web推动了 JS 的发展,而不是 JavaScript 推动了 Web 的发展。今天尽管Web已经如此火爆了,但是人们对Web的期待还不满足。

JavaScript 带来的问题

语法太灵活导致开发大型Web项目困难,所以近几年出现了一些“替代”JS的语言。

TypeScript dart

优点:

缺点:

三大浏览器巨头分别提出了自己的解决方案,互不兼容,这违背了 Web 的宗旨; 是技术的规范统一让 Web 走到了今天,因此形成一套新的规范去解决 JS 所面临的问题迫在眉睫。

JIT的工作原理

在JavaScript发展的前10多年,它的执行速度也确实不快。但是随着时间的推移,到2008年,浏览器性能大战正式打响,许多浏览器加入了 Just In Time 编译器,也叫 JIT。基于 JIT 的模式,JavaScript 代码性能也渐渐变快,正是由于 JIT 的引入使得 JavaScript 性能达到一个转折点,JS 代码执行速度快了10倍。

JS的前10年

解释器:启动速度快,不需要等待整个编译过程就可以运行代码。可是当你运行同样的代码一次以上时,解释器的弊端就显示出来了。比如你执行一个循环,解释器就得一次又一次的进行解释,这就是一种低效的表现。

编译器:需要一段时间对源代码进行编译,然后生成目标文件才能在机器上执行。对于有循环的代码执行的很快,因为它不需要重复翻译代码。另一个不同的是,编译器可以用更多的时间对代码进行优化,以达到更快的运行速度。而解释器是在运行时进行的,这就决定了它不可能在编译期间用太长时间进行优化。

JIT编译器:为了解决解释器的低效问题,浏览器把编译器也引入了,形成混合模式。 不同的浏览器实现这一功能的方式是不同的,不过其基本思想是一致的。在JS引擎中增加一个监视器(也叫分析器)。监视器监控着代码的运行情况,记录代码一共运行了多少次,如何运行等信息。
如果同一行代码运行了多次,这个代码段就被标记了“warm”,如果运行了很多次,则标记成“hot”,所有的优化都在编译器的假设下,如果优化的结果与假设不一致,编译器会去优化。大多数浏览器都做了优化去优化限制,如果超过10次循环优化去优化,那么就不会去优化这部分代码。

但是 JIT 编译器不可避免的造成了新的问题:

这里还有很大的提升空间,那就是消除开销。通过消除开销使得性能上有进一步的提升,这也是WebAssembly所要作的事情之一。

JS解析示意图
WebAssembly解析示意图

Parsing:表示把源代码变成解释器可以运行的代码所花费的时间。 这中间就包括了耗时的 词法分析 和 语法分析
Compile + Optimize:表示优化编译所花费的时间
Re-Optimize:当JIT发现优化假设错误时,去优化所需要的时间
Execute:代码执行所花费的时间
GarbageCollection:垃圾回收清理内存所花费的时间
WebAssembly文件并不是汇编代码,它还是需要再次解析成汇编代码,这需要一点时间。对比之下,发现WebAssembly非常快速。没有GC是因为WebAssembly需要开发人员处理GC
从网络传输方面看,即使是压缩的JS,体积还是比WebAssembly要大的多

评论