专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »Javascript教程 » 如何运行javascript:如何提升JavaScript的运行速度 »正文

如何运行javascript:如何提升JavaScript的运行速度

来源: 发布时间:星期六, 2009年2月14日 浏览:0次 评论:0
="t18">【本文地址】http://cuimingda.com/2009/02/speed-up-your-javascript-part-3.html

递归是拖慢脚本运行速度大敌的太多递归会让浏览器变得越来越慢直到死掉或者莫名其妙突然自动退出所以我们定要解决在JavaScript中出现系列性能问题在这个系列文章第 2篇中我曾经简短介绍了如何通过memoization技术来替代中太多递归memoization是种可以缓存Cache的前运算结果技术这样我们就不需要重新计算那些已经计算过结果对于通过递归来进行计算memoization简直是太有用了我现在使用memoizer是由Crockford写主要应用在那些返回整数递归运算中当然并不是所有递归都返回整数所以我们需要个更加通用memoizer来处理更多类型递归

function memoizer(fundamental, cache){ cache = cache || {} var shell = function(arg){ (!(arg in cache)){ cache[arg] = fundamental(shell, arg) } cache[arg]; }; shell;}这个版本和Crockford写版本有点点区别首先参数顺序被颠倒了原有被设置为第个参数第 2个参数是缓存Cache对象为可选参数并不是所有递归都包含信息内部我将缓存Cache对象类型从转换为对象这样这个版本就可以适应那些不是返回整数递归在shell我使用了in操作符来判断参数是否已经包含在缓存Cache里这种写法比测试类型不是und更加安全und是个有效返回值我们还是用的前提到斐波纳契数列来做介绍说明:

var fibonacci = memoizer(function (recur, n) { recur(n - 1) + recur(n - 2); }, {"0":0, "1":1});同样执行fibonacci(40)这个只会对原有40次而不是夸张331,160,280次memoization对于那些有着严格定义结果集递归算法来说简直是棒极了然而确实还有很多递归算法不适合使用memoization思路方法来进行优化

我在学校时位教授直坚持认为任何使用递归情况如果有需要都可以使用迭代来代替实际上递归和迭代经常会被作为互相弥补思路方法尤其是在另外种出问题情况下将递归算法转换为迭代算法技术也是和开发语言无关这对JavaScript来说是很重要很多东西在执行环境中是受到限制(the importance in JavaScript is greater, though, because the resources of the execution environment are so restrictive.)让我们回顾个典型递归算法比如说归并排序在JavaScript中实现这个算法需要下面代码:

function merge(left, right){ var result = ; while (left.length > 0 && right.length > 0){ (left[0] < right[0]){ result.push(left.sht); } { result.push(right.sht); } } result.concat(left).concat(right);}//采用递归实现归并排序算法function mergeSort(items){ (items.length 1) { items; } var middle = Math.floor(items.length / 2), left = items.slice(0, middle), right = items.slice(middle); merge(mergeSort(left), mergeSort(right));}mergeSort处理就可以返回经过排序注意每次mergeSort都会有两次递归这个算法不可以使用memoization来进行优化每个结果都只计算并使用就算缓冲了结果也没有什么用如果你使用mergeSort来处理个包含100个元素总共会有199次1000个元素将会执行1999次在这种情况下我们解决方案是将递归算法转换为迭代算法也就是说要引入些循环(有关算法可以参考这篇List Processing: Sort Again, Naturally):

// 采用迭代实现归并排序算法function mergeSort(items){ (items.length 1) { items; } var work = ; for (var i=0, len=items.length; i < len; i){ work.push([items[i]]); } work.push(); //in of odd number of items for (var lim=len; lim > 1; lim = (lim+1)/2){ for (var j=0,k=0; k < lim; j, k2){ work[j] = merge(work[k], work[k+1]); } work[j] = ; //in of odd number of items } work[0];}这个归并排序算法实现使用了系列循环来代替递归进行排序由于归并排序首先要将拆分成若干只有个元素这个思路方法更加明确执行了这个操作而不是通过递归隐晦完成work化为包含堆只有个元素在循环中每次会合并两个并将合并后结果放回work执行完成后排序结果会通过work个元素返回在这个归并排序实现中没有使用任何递归同样也实现了这个算法然而这样做却引入了大量循环循环次数基于要排序中元素个数所以我们可能需要使用在上篇讨论过技术来进行修订处理这些额外开销

整理总结下基本原则不管是什么时候使用递归时候都应该小心谨慎memoization和迭代是代替递归两种解决方案最直接结果当然就是避免那个提示脚本失控对话框

0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: