我在做一个 Javascript 版的公历农历转换程序,功能完成后,需要对性能做优化。计算算法是在网上找的,原作者对历法的转换很精通,但对程序性能没有仔细考虑,当计算量大的时候,会给用户的浏览器造成很大压力,给用户的感觉就好像浏览器假死一样。
我花了2天时间在性能优化上,并在不同的浏览器下做对比测试,发现一个比较重要的差别,IE、Firefox 和 Chrome 之间的区别很大。
通常,生成一个月的日历,最多需要计算42天(可参考Google Calendar,每行代表一周7天,最多可能有6行)。
性能测试的时候,我让程序连续计算3年,共36个月,1000多天。
总的运行时间是:
IE7: 2.828 s
Safari3: 1.016 s
Firefox3: 0.885 s
Opera9: 0.765 s
Chrome: 0.281 s
这下终于见识了 Chrome 采用的 Javascript V8 引擎的强大实力!
以上统计结果都是测试3次取结果平均值。
程序运行到这个时间量级,已经是我优化过了的,最开始的程序,完成2年的计算,也就是上述运算量的三分之二,Firefox3用了8秒左右,Chrome很棒,用了2秒,而IE,30秒过后,浏览器直接问我是否要强制停止脚本运行,实际上我还从来没有在IE上成功执行过!
关于浏览器性能的差别,你可以用IE和Chrome打开淘宝的同一个比较复杂的页面,感受一下拖拉机与飞机的区别。
上面是浏览器的差别,下面我再给一些 Javascript 程序上的差别。
我的农历转换算法,有一个关键函数,需要多次调用,这个正是性能的瓶颈所在。
观察了调用方式和次数,这个函数运行了33000多次,而总共参数的变化只有1000次左右,如果加入缓存,可以减少97%的运算量!!!
我采用hash表的方式对每个输入的key做缓存,由于函数的参数是年月日,共3个,所以需要把这3个参数拼接成一个key。
最开始,我用字符串拼接,y m d 之间用 “_” 下划线连接起来,但仅仅是一个这样的字符串操作,程序运行时间就从0.8秒增加到1.1秒,增加了将近40%的时间!!
这是不能接受的,这将使我的缓存优化方式变得毫无意义。
农历算法的大部分关键代码,都是数字上的计算,代码很多,但好像没有产生性能瓶颈,这给了我启发。
我改用数字索引,把 y m d 用加法和乘法算出类似于 20081026 这样的整数,这样运行时间从0.789 s增加到0.853 s,只有不到10%的增加。
我的缓存,只能把运行时间降低20%到30%,所以用整数索引,可以达到优化的目的。
http://leakon.googlecode.com/svn/trunk/leakon/javascript/wannianli/nice/
很愿意与大家一起分享,一起分析,一起应用~~
原创文章,请尊重我对互联网的贡献,谢谢!