×

WebAssembly的起源及实践分析

消耗积分:2 | 格式:rar | 大小:0.9 MB | 2017-09-30

分享资料个

在浏览器之争中,Chrome凭借Java的卓越性能取得了市场主导地位,然而由于Java的无类型特性,导致其运行时消耗大量的性能做为代价,这也是Java的瓶颈之一。WebAssembly旨在解决这一问题。本文从WebAssembly的起源到开发实践对其做全面探究,帮助开发者对WebAssembly有全面的了解。
  缘起
  让我们从浏览器大战说起。微软凭借Windows系统捆绑Internet Explorer的先天优势击溃Netscape后,进入了长达数年的静默期。而Netscape则于1998年将Communicator开源,并由Mozilla基金会衍生出Firefox浏览器,在2004年发布了1.0版本。从此,第二次浏览器大战拉开帷幕。这场大战由Firefox浏览器领衔,Safari、Opera等浏览器也积极进取,Internet Explorer的主导地位首次受到挑战。2008年Google推出Chrome浏览器,不但逐步侵蚀Firefox的市场,更是压制了老迈的Internet Explorer。在此次大战之后的2012年,StatCounter的数据指出Chrome以微弱优势超越Internet Explorer成为世界上最流行的浏览器。
  分析Google Chrome浏览器战胜Internet Explorer的原因,除了对Web标准更友善的支持外,卓越的性能是其中相当重要的因素,而浏览器性能之争的本质则体现在Java引擎。此前,Java引擎的实现方式经历了遍历语法树到字节码解释器等较为原始的方式,将每条源代码翻译成相应的机器码并执行,并不保存翻译后的机器码,使得解释执行很慢。2008年9月,Google发布了V8 Java引擎。V8被设计用于提高Web浏览器中Java的执行性能,通过即时编译JIT(Just-In-Time)技术,在执行时将Java代码编译成更为高效的机器代码并保存,下次执行同一代码段时无需再编译,使得Java获得了几十倍的性能提升。
  然而,Java是个无类型(untyped,变量没有类型)的语言,这直接导致表达式c=a+b有多重含义:
  a、b均为数字,则算术运算符+表示值相加;
  a、b为字符串,则+运算符表示字符串连接;
  ……
  表达式执行时,JIT编译器需要检查a和b的类型,确定操作行为。若a、b均为数字,JIT编译器则将a、b确认为整型,而一旦某一变量变成字符串,JIT编译器则不得不将之前编译的机器码推倒重来。由此可见,Java的无类型特性建立在消耗大量性能代价的基础之上。即便JIT编译器在对变量类型发生变化时已进行相应优化,但仍然有很多情况Java引擎未进行或无法优化,例如for-of、try-catch、try-finally、with语句以及复合let、const赋值的函数等。
  由此可见,Java的无类型是Java引擎的性能瓶颈之一,改进方案有两种:一是设计一门新的强类型语言并强制开发者进行类型指定;二是给现有的Java加上变量类型。
  微软开发的Type属于第一种改进方案。它是扩展了Java特性的语言,包含了类型批注,编译时类型检查,类型推断和擦除等功能,Type开发者在声明变量时指定类型,使得Java引擎能够更快将这种强类型的语言编译成弱类型。
  看看第二种方案:
  WebAssembly的起源及实践分析
  代码1
  代码1表示带有两个参数(a和b)的Java函数,和通常Java代码不同的地方在于a=a | 0及b=b | 0,以及返回值后面均利用标注进行了按位OR操作。这么做的优点是使Java引擎强制转换变量的值为整型执行。通过标注加上变量类型,Java引擎就能更快地编译。
  既然增加变量类型能够提升Web性能,有没有办法将静态类型代码例如C/C++等转换成Java指令的子集呢?上面的这段代码恰恰是作为Java子集的asm.js,由代码2的C语言编译而来:
  WebAssembly的起源及实践分析
  代码2
  事实上,早在1995年起就已经有Netscape Plugin API(NPAPI)在内的可以使用浏览器运行C/C++程序的项目在开发。而2013年问世的asm.js是目前较为广泛的方案。asm.js是一种中间编程语言,允许用C/C++语言编写的计算机软件作为Web应用程序运行,并保持更好的性能,而Mozilla Firefox从版本22起成为第一个为asm.js特别优化的网页浏览器。
  Google也同样在为原生代码运行在Web端而努力。Google Native Client(NaCl)采用沙盒技术,让Intel x86、ARM或MIPS子集的机器码直接在沙盒上运行。它能够在无需安装插件的情况下从浏览器直接运行原生可执行代码,使Web应用程序可以用接近于机器码运作的速度来运行。而Google Portable Native Client(PNaCl)则稍有变化,通过一些前端编译器将C/C++源代码编译成LLVM的中间字节码而不是x86或ARM代码,并且进行优化以及链接。
  

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !