天天看点

02. WebApp2.0时代启程:Cocos2d-JS为什么选择SpiderMonkey(二)

紧接上文,cocos2d-js为我们提供了图形引擎、物理引擎、js引擎等基础库,在多终端时代提供了非常nice的游戏引擎,在浏览器普及在各个终端的今天,为什么还要单独搞一套js引擎呢?

我们先看看使用spidermonkey的技术产品有哪些?

02. WebApp2.0时代启程:Cocos2d-JS为什么选择SpiderMonkey(二)

没有看错,spidermonkey就是firefox浏览器的js虚拟机(后续简称jsvm),firefox的实力也是赢得了众多前端开发者的芳心;cocos2d-x更是不用说了,东亚97%的2d游戏开发者的选择,手游开发者的入门技能,k-3d也是在aepixi(我们内部实现的跨平台的js图形引擎)的3d技术的源泉,在众多新兴的图形引擎中,我们都找到spidermonkey的影子,为什么开发者不选择javascriptcore或者v8呢?

主流的js引擎对比,spidermonkey vs v8 vs javascriptcore (vs rhino)

02. WebApp2.0时代启程:Cocos2d-JS为什么选择SpiderMonkey(二)

a) interpreter: 解释执行,js和java在运行时都是解释执行的一种高级语言,重要的特性之一,就是无类型untyped,比如,在执行js语句时,a = b + c;因为表达式是无类型的,js执行过程在不同的场景,可能有多种不同的含义,如:

(i)b、c都是number类型,那么+号表示数字相加,

(ii)b、c都是字符串类型,那么+号表示字符串链接

interpreter是如何解释执行呢?

(i)从内存中读取表达式 a = b + c;

(ii)从内存中读取b、c的类型,确定操作符的含义

(iii)unbox b、c,获取真正的value

(iv)执行 b + c,(唯一有效的步骤)

(v)将结果box to x

jit特性,提升js运行速度10 ~ 100倍,又是如何提速的呢?

(i)判断b、c的类型

(ii)执行b+c(唯一有效步骤)

(iii)写入a

可以看到jit的运行方式缩短了js运行步骤,但不是所有场景都是可以使用jit的,比如 string + undefined,这个时候需要回归解释执行了。

b) interpreter vs jit,本质来说,jit确实极大的提升了js的运行速度,从2011年之后,几乎所有的javascript引擎都开启了jit功能,(除了android4.4.2以后,为什么呢?下一章节我们重点解读google的密谋)

js引擎之争与安全

上图中是2014年的分析,从android4.4.2、ios8以后,v8和javascriptcore分别增加了jit的功能,android的webkit也同步了最新的chrome的内核,然而,仍然没有开放js引擎的插件机制(pnp)功能,理由很简单,那就是如果开启这个功能,开发者可以直接访问js的底层数据,浏览器的安全沙箱,就没有任何意义,开发者可以肆意的窥探不同网站的内部数据,谷歌和苹果怎能轻易放手?

spidermonkey的出现解决了这个问题,作为独立的js引擎,体积小(2.5m)、运行速度快、支持jit、pnp等特性,成为了开发的首选,虽然国内对spidermonkey的介绍不多,但无法阻止前端开发者对js的追求,通过简单地代码,可以让你的c++程序轻松的支持javascript脚本。

js的优势与弥补缺陷

js在逻辑处理和高级语言特性方面如:闭包、函数、类型转换、node.js上,极大的方便了前端开发同学,又像java一样不用担心内存释放,不仅在在h5领域拥有霸主地位,近年来扩张到服务器开发、链接数据库,处理高级业务上,也大展手脚。其所见即所得的开发方式,更是让native开发同学羡慕不已。

当然,缺陷在上面的解释执行的过程中,也暴露无遗,native的开发方式上,不仅可以高效的执行指令,而且可以做到硬件加速,在ios平台就有专门为矩阵运算的硬件加速,这些领域,目前还是js无法做到的。

我们是否可以把一些复杂的计算、如加解密、编解码、图像处理、浮点数、矩阵处理,用c/c++实现,并把这些api开放到js引擎中呢?

js单线程的性能比java要好!

我知道,只要说一句php是世界上最好的语言,马上程序员们就不淡定了。先不要慌者评价,我们看看js和java的虚拟机架构图

02. WebApp2.0时代启程:Cocos2d-JS为什么选择SpiderMonkey(二)

我们可以清楚的看到,java和js都有一个底层的跨平台的虚拟机,且都是解释执行的高级语言和gc机制,从架构上看,不同的是java有自己的独立的内存结构,通过jni这一层将java的内存转换成c++内存,才可以调用底层的内核资源,而js运行空间完全是与c++一样的内存控件,完全是c++代码在运行。

我们知道java启动时,需要申请独立的内存控件和自己的堆栈管理,最终运行时还是会翻译成c/c++,js在解释之后,直接交给了c++对象来处理,少了一层jni的中介服务,必然性能会有所提升。今年来兴起的node.js不也是靠c/c++撑腰,才这么牛逼哄哄的嘛?

(总结)spidermonkey相对webkit、blink而言,作为一个非主流的js的引擎,把握好了终端领域需要一个轻量级、可定制、体积小、运行快的js虚拟机的需求下,配合移动互联网的兴起,弯道超车,在独立游戏引擎、脚本引擎领域,成了目前众多开发者的首选,是一部屌丝逆袭的励志案例。