Category Archives: 35Days

颠覆网络35天 ─ TraceMonkey

这个系列的翻译停了好久,:( 其实是心有余力不足,呵呵。这几天看到Hacks不断出来非常棒的文章,所以还是尽量翻译一些,坚持这个系列。不过就不保证顺序了,呵呵──主要也是这篇讲述TraceMonkey的文章太棒,想先翻这一篇 原文地址:an overview of TraceMonkey 系列地址:颠覆网络35天 ==================================== 本文作者为David Mandelin,──Mozilla JavaScript团队工作人员。 Firefox 3.5拥有一个全新的JavaScript引擎,叫做TraceMonkey,在该引擎上跑JS应用要比Firefox 3快到3-4倍,从而为现有的网络应用加速。这篇文章大致的描述一下在TraceMonkey中包括的重要部件,以及他们是如何加速JavaScript的。同样,在了解这些之后,你也就能知道什么样的网络应用通过TraceMonkey能够获得最大的提速,以及怎么样来写您的程序获得更大的性能提高。 为什么提速JS很难:动态类型 类似于JavaScript和Python这样的高级动态语言通常使得编程效率非常高,但是同类似Java或者C这样的静态语言相比,他们要慢一些。按照经验来说,一个JS程序通常要比同等的Java程序慢10倍。 像JS这样的动态语言比像Java或者C这样的静态语言慢主要有两个原因。第一个原因是在动态语言中,通常不太容易在执行之前知道值的类型信息。因此,语言本身必须使用一个通用的格式存储所有的值并且使用通用的操作来处理他们。 相反,在Java中,程序员声明变量和方法的类型,编译器可以在运行之前就知道这些值的类型。编译器可以使用特定的格式和操作来处理这些值,而这个过程要比通用的格式和操作快很多。下面,我会把这类操作叫做类型特定处理。 动态语言运行慢的第二个原因是,动态脚本语言通常实现为解释器,也就是由解释器执行;而静态语言通常被编译为原生代码。解释器可以很容易的构造,但是他们需要额外的运行时间来处理跟踪他们的内部状态。像Java这样的语言会被编译成机器语言,基本上是不需要内部运行状态跟踪的。 让我们用一张图片来描述的更具体。这里有一个简单的加法的分解动作示意图,我们来计算一下:a + b,这里a和b均为整数。首先,我们忽略最右边的柱状图,集中在Firefox 3的JavaScript解释器和Java JIT执行效率的比较上。每个纵列都表示在某种语言上这个加法运算要做的分解动作。时间从上到下进行,每个不同颜色的盒子高度基本表示进行该分解动作需要的时间。 在中间,Java简单的运行一条机器指令:“加”命令,运行时间为T(一个处理器周期)。因为Java编译器预先知道运算值为标准的机器整数类型,她可以直接使用标准的整数加法机器指令。完了。 在左边,SpiderMonkey(FF3中的JS解释器)需要大概40个T。棕色部分的盒子部分为整个解释器的开销:解释器需要读取加操作,然后跳到解释器的通用加操作代码部分。橘色的盒子部分表示由于解释器不知道运算值的类型造成的额外工作。解释器需要解开a和b的通用描述格式,判断出他们的类型,选择特定的加法运算,把值转换为正确的类型,加法进行完之后,还需要把结果转换为通用的描述格式。 上面的图表显示,使用解释执行要比编译器慢一些,而使用不带任何类型信息的解释执行要慢很多。如果我们希望JS能够被运行的快一些,根据Amdahl定律,我们需要做点关于类型的事情。 通过跟踪获得类型 在TraceMonkey中,我们的目标是没有蛀牙,不对,我们的目标是编译出类型特定的代码。为了实现这个目标,TraceMonkey需要知道变量的类型。但是JavaScript本身是没有类型的,而我们前面也说过JS引擎基本上是无法在运行前知道类型的,但是我们还要在运行之前编译出本地代码,貌似无路可走了。 让我们换个角度来看这个问题。如果我们让程序在解释器中先跑一段,那么引擎就可以直接觉察到数值的类型了不是。然后,引擎可以使用这些类型来编译产生更快的类型特定的代码。最后,引擎就可以开始运行这些类型特定的代码,于是就运行的更快了~ 这个想法还有几个关键的细节。首先,当程序运行时,即便有很多的if语句和其他的程序分支,他始终在其中一个分支上。所以,引擎不太有机会觉察到方法中所有数值的类型──引擎通过路径来观察数值,我们称之为轨迹 Traces。因此,标准的编译器是对整个方法或者过程进行编译,而TraceMonkey是针对轨迹进行编译。运行期轨迹编译有个好处是在轨迹上的函数调用是内联inline的,这使得轨迹上的函数调用非常的快。 第二,编译类型特定的代码是占用运行时间的。如果一块代码仅仅会运行一次或少量的几次──这在网页代码中比较常见──他可能会占用更多的时间来编译和运行反而可能还不如直接在解释器里面运行来的快了。所以,他应该只去编译热代码(被运行很多次的代码)。在TraceMonkey中,我们通过跟踪循环来安排热代码。TraceMonkey开始在解释器中运行所有代码,并开始为循环记录轨迹中的热代码。 仅跟踪热循环代码结果之一就是:只运行几次的代码并不会在TraceMonkey中得到提速。而这通常不会影响实际运行效果,因为仅运行几次的代码通常很快就完事了,你可能都不会注意到他。另一个结果是那些不热的循环代码基本上不被运行,也不会被编译,从而节省编译时间。 最后,上面我们提到TraceMonkey是通过观察执行过程来判断数值类型,基本上算是事后诸葛亮的做法,可能并不能保证将来的结果──更准缺点说算是事中诸葛亮:下次这部分代码被运行时,数值类型可能变了,或者第500次的时候开始变了也说不定。当我们已经产生好针对数字类型编译的代码之后,值变成字符串类型了,那就糟糕了。所以,TraceMonkey必须在编译代码中加入类型检查。如果没有通过检查,TraceMonkey必须离开当前轨迹,使用新类型重新编译这个轨迹上的代码。这就意味着拥有很多分支或者类型经常改变的代码在TraceMonkey中不一定能得到多少性能上的提高,因为他需要花费运行时间来编译多出来的轨迹或者从这个轨迹跳到那个等等。 TraceMonkey操作起来~ 现在,我们通过一些示例来看一下TraceMonkey的实际操作情况:我们这里要完成的工作是把从1到N的整数都加到一个起始值上: function addTo(a, n) { for (var i = 0; i < n; ++i) a = a + i; […]

Firefox 3.5 震荡波

还记得去年Firefox 3发布时候的营销活动──下载日吗?号召全世界的朋友在那一天开始下载Firefox 3。 今年Firefox 3.5同样有个超级牛的营销活动──震荡波。 参与进来非常容易。在自己所在地方的下午3:50,大家一起在twitter、饭否、facebook、豆瓣、开心、校内、白社会等等网站上一起发送关于Firefox 3.5发布的信息。──还有一个小时就要来了噢~~ 您可以发送像下面这样的话──或者自己写(记得加上#fx35的标签): 震荡全世界!现在就下载 Firefox 3.5:http://www.mozillaonline.com/ #fx35 (发送到Twitter) Shock ‘n’ Roll!现在就下载 Firefox 3.5:http://www.mozillaonline.com/ #fx35 (发送到Twitter) 拥有超强的内核动力!现在就下载 Firefox 3.5:http://www.mozillaonline.com/ #fx35 (发送到Twitter)

Firefox 3.5 正式发布

Firefox 3.5终于正式发布,而前面这一段时间里,我也基本上以一定拖拉的速度在帮助翻译“颠覆网络35天”系列文章,加上3.5非常强劲的内核动力,我对他的正式发布还是很期待的。 正好hacks.mozilla.org上也写了一篇”Firefox 3.5 is out“,我连翻译带自己白话凑一篇,呵呵──这几天在忙着升级网站内容到3.5,所以翻译35天系列的任务也放下,好在没有落下太多。 在35天项目一开始的文章里,Chris Blizzard就讲过,Firefox 3.5不仅仅是对用户的一次重要升级,对整个互联网都是一次重要的升级,浏览器毕竟属于互联网基础设施的一部分,对HTML 5等规范的支持让互联网真得开始走入一个新时代。Firefox 3.5对于用户的升级主要是在速度等方面,对于开发者的升级意义重大。从Firefox 3.5一系列提供的开发者特性上就可以看出这一点。 从35天项目开始,每天基本上都会介绍一个新特性,并加上一个很棒的演示。现在这个项目走到一半,按照Chris Blizzard的话说,情况发生了很大的变化,很多开发者都主动制作演示,说明他们开始接收并喜欢这些新特性,而Firefox 3.5的强劲内核使得开发者拥有更大的想象空间,不断的可以突破和改变过去。如果真的喜欢Firefox 3.5并且想参与进来的话,那么就帮我们多多传播声音,在Twitter上,在饭否上,在开心上等等等等。如果还不知道这是怎么一回事,那就先用用Firefox 3.5吧,保证你会喜欢他~~

颠覆网络35天 ─ 文字阴影聚光灯

原文地址:the text-shadow spotlight 系列地址:颠覆网络35天 ==================================== Zachary Johnson制作了另一个很炫的演示 has put together another fun demo。他使用JavaScript和text-shadow属性制作了一个聚光灯效果。已经被嵌入到下面了。如果看不到的话,查看他的博客文章。 使用Firefox 3.5观看演示

颠覆网络35天 ─ 使用localStorage保存数据

原文地址:saving data with localStorage 系列地址:颠覆网络35天 ==================================== 本文作者为Jeff Balogh。Jeff就职于Mozilla的互联网开发团队。 localStorage是Web Storage互联网存储规范中的一部分,现在在Firefox 3.5中得到支持。localStorage提供了简单的 provides a simple Javascript API,用来在浏览器中持久化key-value键值对。应该注意的是不要同SQL数据库存储提案混淆,后者是另外单独的(同时也是有争议的)互联网存储规范的一部分。键值对可以存储在cookie中,不过你一定不想这么做。Cookie在每次请求中都会被发送到服务器端,如果使用大数据集合的话会有性能问题,同样也在传输中会有安全问题,而且也许你不得不为了处理这些数据特别写大量代码,例如把cookie像数据库那么使唤。 这里有一个简单演示,可以把textarea中的内容存储到localStorage。你可以改变文字,打开新标签页,可以看到更新过的内容。或者重启浏览器,你的文字还会在那里。 使用localStorage最简单的方式就是像一个正常对象那样的使唤他: >>> localStorage.foo = ‘bar’ >>> localStorage.foo “bar” >>> localStorage.length 1 >>> localStorage[0] “foo” >>> localStorage['foo'] “bar” >>> delete localStorage['foo'] >>> localStorage.length 0 >>> localStorage.not_set null 如果喜欢使用函数的话,我们也有类似的API: >>> localStorage.clear() >>> localStorage.setItem(‘foo’, ‘bar’) >>> localStorage.getItem(‘foo’) “bar” >>> localStorage.key(0) “foo” […]

颠覆网络35天 ─ 使用SVG和APNG制作动画纹理映射

原文地址:using SVG and APNG to create an animated texture map 系列地址:颠覆网络35天 ==================================== 昨天我们介绍了使用SVG来映射3D数据的演示。今天我们再介绍一个Hans的演示:在浏览器中动态为动画添加纹理效果。 他使用了同之前文章中一样的技术,但是这次加载了一个动画PNG图片然后在图片上映射一个随机的图片纹理,这里使用了他的SVG 投影技术。结果非常赞!查看演示: 在Firefox 3.5中查看演示