【问题标题】:real world example of memoization in javascript?javascript中memoization的真实世界示例?
【发布时间】:2012-05-23 13:58:27
【问题描述】:

我找到了诸如阶乘计算之类的示例来解释memoization。这些很有帮助,但我正在寻求更深入的了解。

我想知道是否有人可以描述这种技术在现实世界中的应用,以及为什么他们使用它而不是递归或者他们认为使用记忆化可能有助于他们优化的任何其他方法。

【问题讨论】:

    标签: php javascript recursion memoization


    【解决方案1】:

    记忆比缓存更具体一点。

    考虑使用选择器在 DOM 中搜索元素,就像使用 jQuery 一样。说,$('.some-selector')。在这种情况下,我调用函数$,告诉它为我找到所有具有CSS 选择器'.some-selector' 的元素。假设文档很大,需要多次调用$('.some-selector')

    您可以假设每次调用$('.some-selector') 都会返回相同的结果,因此,每次调用它时进行实际处理都是浪费精力。因此,$ 可以使用参数(在本例中为“.some-selector”)作为某个查找表或字典中的键。第一次使用该参数调用函数时,它会正常处理,使用参数作为键将结果放入字典中,然后返回结果。后续调用会发现该键在字典中有一个值,表示已经计算过的结果,所以它只是返回那些之前的结果。最终效果是您不会浪费时间寻找您已经知道的结果。

    一个粗略的 JavaScript 示例:

    var _dictionary = {};
    
    function $(selector) {
       if (_dictionary[selector]) return _dictionary[selector]; // lookup the results of the selector and return them if they exist
    
       // otherwise, execute the function's logic normally
       // TODO: search logic
       var results = doSearch();
    
       _dictionary[selector] = results;
    
       return results;
    
    }
    

    This link 更详细,甚至包括一个通用的memoize JS 函数,可用于任何其他函数。

    【讨论】:

    • 超级/干净的解释
    【解决方案2】:

    您可以使用 memoization 进行各种缓存。例如,您可以缓存一些 ajax 调用的结果。

    例子:

    var cache = new Array()
    
    function memoized_ajax(url, callback) (
      if (cache[url]) {      
        callback(cache[url]);  // we already know the result for this url
      }
      else {
        $.ajax({
          url: url,
          success: function(data) {
            cache[url] = data;   // we will remember result for this url
            callback(data);
        });
      }
    }
    

    【讨论】:

    • 对于初学者来说,缓存是记忆的同义词吗?在您的示例中,通过缓存是否只是将 ajax 调用的结果分配给局部变量?
    • 是的,你缓存了函数调用的结果,但是以这样一种方式,它对函数调用的用户是透明的,请参阅我更新的答案或@HackedByChinese 示例
    • 结果如何不会“对函数调用的用户透明”?
    • “记忆”和“纯缓存”之间的区别在于缓存发生在函数调用的“幕后”。在这种情况下,“用户”是程序员“使用”函数,他不必编写“缓存”。
    • 还请注意,我的示例对于记忆来说有点不寻常,因为我还使用了回调函数。但是由于在javascript中处理回调函数很常见,所以我使用了这个例子。
    【解决方案3】:

    如果你愿意,你可以删除它,因为我无法真正回答你的问题(即给你一个使用记忆的例子),但我想指出记忆是为了解决完全不同类型的问题比递归。记忆化存储方法调用的输出,以便派生未来相同方法调用(相同参数和对象绑定)的结果是查找而不是计算。递归是一种函数算法。这意味着它们并不反对,因为您可以记住递归函数的输出。

    【讨论】:

    • 感谢您澄清如何将记忆化与递归一起使用,并且它们不是直接可比较的概念
    猜你喜欢
    • 1970-01-01
    • 2010-11-23
    • 2016-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-12
    • 1970-01-01
    相关资源
    最近更新 更多