提升JavaScript的运行速度,递归是拖慢脚本运行速度的大敌之一。太多的递归会让浏览器变得越来越慢直到死掉或者莫名其妙的突然自动退出(在firefox中弹出脚本无响应的对话框),所以我们一定要解决在JavaScript中出现的这一系列性能问题。在这个系列文章的第二篇中,我曾经简短的介绍了如何通过 memorization技术来替代函数中太多的递归调用。memoization是一种可以缓存之前运算结果的技术,这样我们就不需要重新计算那些已经计算过的结果。对于通过递归来进行计算的函数,memoization简直是太有用了。我现在使用的memoizer是由Crockford写的,主要应用在那些返回整数的递归运算中。当然并不是所有的递归函数都返回整数,所以我们需要一个更加通用的memoizer()函数来处理更多类型的递归函数。
function memoizer(fundamental, cache){ cache = cache || {} var shell = function(arg){ if (!(arg in cache)){ cache[arg] = fundamental(shell, arg) } return cache[arg]; }; return shell;}这个版本的函数和Crockford写的版本有一点点不同。首先,参数的顺序被颠倒了,原有函数被设置为第一个参数,第二个参数是缓存对象,为可选参数,因为并不是所有的递归函数都包含初始信息。在函数内部,我将缓存对象的类型从数组转换为对象,这样这个版本就可以适应那些不是返回整数的递归函数。在shell函数里,我使用了in操作符来判断参数是否已经包含在缓存里。这种写法比测试类型不是undefined更加安全,因为 undefined是一个有效的返回值。我们还是用之前提到的斐波纳契数列来做说明:
var fibonacci = memoizer(function (recur, n) { return 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){ if (left[0] < right[0]){ result.push(left.shift()); } else { result.push(right.shift()); } } return result.concat(left).concat(right);}//采用递归实现的归并排序算法function mergeSort(items){ if (items.length == 1) { return items; } var middle = Math.floor(items.length / 2), left = items.slice(0, middle), right = items.slice(middle); return merge(mergeSort(left), mergeSort(right));}调用mergeSort()函数处理一个数组,就可以返回经过排序的数组。注意每次调用mergeSort()函数,都会有两次递归调用。这个算法不可以使用memoization来进行优化,因为每个结果都只计算并使用一次,就算缓冲了结果也没有什么用。如果你使用mergeSort()函数来处理一个包含100个元素的数组,总共会有199次调用。1000个元素的数组将会执行1999次调用。在这种情况下,我们的解决方案是将递归算法转换为迭代算法,也就是说要引入一些循环(关于算法,可以参考这篇《List Processing: Sort Again, Naturally》)。
分享到:
相关推荐
在本文中,我们要探讨的知识点集中于一个计算机视觉领域的开创性研究方向——“Meta-Learning without Memorization”(无记忆的元学习)。这篇开源论文发表于ICLR 2020(国际机器学习会议),由Mingzhang Yin等人...
Use an interactive program for memorization, practice, and correction, with 89 examples, full TOC. 资料来自互联网,仅供借鉴,请保护作者及出版商知识产权。
今天我们要探讨的“Memorization Tool”便是一个基于Python编程语言打造的记忆辅助工具,它能帮助我们更好地管理、巩固和记忆各种技术知识点。 “Memorization Tool”源自一个在线培训任务,其主要目标是通过智能化...
在cards/ 目录中,您会注意到已经有一个json (.js) 文件。 您可以将其用作模板。 下面是一个典型的 json 文件应该是什么样子的一般分类: var memory = { groups : [ { group : <groupname> , cards : [ ...
批归一化是深度学习中常用的正则化技术,这篇论文提出改进策略以减少训练过程中的波动,提高模型的训练效率和泛化性能。 综上所述,这些论文涵盖了计算机视觉的多个重要方面,包括但不限于深度学习、自我监督、目标...
本文介绍了一种高效减少贝叶斯神经网络(Bayesian Neural Networks, BNNs)计算复杂度的方法,该方法通过特征分解与记忆(Decomposition and Memorization, DM)策略来实现。针对现有BNNs面临的高计算复杂度问题,...
当主耶稣基督的跟随者对他的话语和他儿子的拯救信息的知识增长时,上帝很高兴。 背诵经文是值得称赞的,但初学者可能会发现它令人生畏。 InVerse 用 15,300 个预加载的诗句简化了这一点
动态规划(Dynamic Programming)是一种强大的算法设计方法,广泛应用于计算机科学和信息技术...理解并掌握动态规划技术对于任何专业的 IT 从业者来说都至关重要,因为它可以解决实际工作中遇到的许多复杂优化问题。
在实际应用中,用户可以根据powermem的反馈,制定个性化记忆计划,结合间隔重复策略,有效克服遗忘,提高学习成果。同时,由于它是开源软件,用户不仅可以自由使用,还可以参与到项目的开发和优化中,共同推动其进步...
可用脚本在项目目录中,可以运行:yarn start 在开发模式下运行应用程序。 打开在浏览器中查看它。 如果您进行编辑,则页面将重新加载。 您还将在控制台中看到任何棉绒错误。yarn test 在交互式监视模式下启动测试...
Put it all together with the Zebreto effective-memorization flashcard app Deploy apps to the iOS App Store and Google’s Play Store Paperback: 272 pages Publisher: O'Reilly Media; 1 edition (December...
《Wide & Deep Learning for Recommender System》这篇论文探讨了如何在推荐系统中融合宽线性模型(Wide)和深度神经网络(Deep)的优势,以实现更好的记忆化(memorization)和泛化(generalization)。在推荐系统...
它面临的挑战在于既要能够记住历史数据中的模式(memorization),也要能泛化到新的特征组合(generalization)。 传统的逻辑回归(LR)模型简单、可解释且易于并行化,但依赖于手动特征工程,对于未出现过的特征...
Become a SuperLearner - Learn Speed Reading & Advanced Memorization
Pinterest的Related Pins案例提供了一个实用的例子,展示了如何在实践中逐步构建和优化推荐系统,平衡技术复杂性和实际效果。通过不断迭代和学习,推荐系统可以成为驱动用户engagement和Save Propensity的关键驱动力...
C mixup是一种简单的学习原则,旨在缓解深度神经网络中的 memorization 和对对抗性示例的敏感性问题。该方法通过训练神经网络在一对示例及其标签的凸组合上,regularize 神经网络以便在训练示例之间表现出简单的线性...
例如,记忆单词“shrimp”时,可以通过与家庭晚餐中妈妈准备的海鲜大餐的情境相结合,让单词与真实生活场景相融合,从而更容易回想起单词的含义和相关的情感体验。 其次,图像图形记忆法(Vivid Images ...
动态规划有两种主要的解决方法:递推(bottom-up method)和记忆化搜索(top-down with memorization)。递推方法是从最基本的子问题开始,逐步解决更大的子问题,直到解决原问题。记忆化搜索方法是从原问题开始,...