|
Function Cache
Всем привет!
Задача в том, что: 0) Создается некоторая функция, принимающая N аргументов; 1) Создается кэширующая функция, которая принимает вышеуказанную в качестве фунарга и дальше с возвращенным ей значением мы можем работать следующим образом: - если такая функция-обертка вызывается с новым набором аргументов, то выполняется оригинальная функция; - в противном случае, если вызов с такими аргументами уже был, то возвращается закэшированный результат, без вызова. Вот оригинальное описание: "If you are calculating complex things or execute time-consuming API calls, you sometimes want to cache the results. In this case we want you to create a function wrapper, which takes a function and caches its results depending on the arguments, that were applied to the function." Мой код: function cache(func) { var cached_func = func, cached_func_data = []; return function() { var args_len = arguments.length, i, j; if (!cached_func_data.length) { return callCachedFunc(arguments); } for (i = 0; i < args_len; i++) { for (j = 0; j < cached_func_data[i].args.length; j++) { if (cached_func_data[i].args[i] === arguments[i]) { continue; } return cached_func_data[i].res; } return callCachedFunc(arguments); } function callCachedFunc(arguments) { var cache_obj = {}; cache_obj.args = Array.prototype.slice.call(arguments); cache_obj.res = cached_func.apply(null, arguments); cached_func_data.push(cache_obj); return cache_obj.res; } } } Прошу провести ревью кода. Решение не полностью корректно, но я не могу пока что, к большому своему огорчению, найти ошибку. Спасибо. |
Вот пример использования:
var complexFunction = function(arg1, arg2) { /* complex calculation in here */ }; var cachedFunction = cache(complexFunction); cachedFunction('foo', 'bar'); // complex function should be executed cachedFunction('foo', 'bar'); // complex function should not be invoked again, instead the cached result should be returned cachedFunction('foo', 'baz'); // should be executed, because the method wasn't invoked before with these arguments Заранее благодарен за любые комментарии по делу. |
|
nerv_,
чушь собачья a=Object.create({a: 1}) b=Object.create({a: 2}) fu=function(){ var f=function(arg){return arg.a} return function(){alert(JSON.stringify(arguments)); return f(arguments[0])} }() alert(fu(a)) alert(fu(b)) // {"0":{}} // 1 // {"0":{}} // 2 Закешировали, ага. |
я вчера было уже хотел выложить вариант с двумя массивами, но вариант nerv_ c cache[stamp] дал понять, где настоящий скил :)
в качестве отработки при помощи FineReader-a извлёк код nerv_ (шутка :D ) function f(a, b, c) { return a * b + c; }; function cacheFn(fn) { var cache = {}; return function () { var stamp = JSON.stringify(arguments); console.log(cache); if (!(stamp in cache)) { cache[stamp] = fn.apply(this, arguments); console.log("call: " + cache[stamp]); } console.log("cache: " + cache[stamp] + "\n\n"); return cache[stamp]; } } var cacheF = cacheFn(f); cacheF(2, 2, "asdf"); cacheF(2, 2, "asdf"); cacheF(2, 3, "asdf"); cacheF(2, 3, "asdf"); |
if (!cache.hasOwnProperty(stamp)) {/*... */} а так не лучше будет? |
Цитата:
|
Цитата:
Общепринятое название функции memorize (у меня на скрине опечатка, скопипастил название у lowdash), от memorization https://lodash.com/docs#memoize Читайте Стоян Стефанов - JavaScript. Шаблоны, там все есть Ну, и, разумеется, такая функция принимает только примитивы + json like objects. Если очень хочется пихать объекты с циклическими ссылками, то массивы. |
Цитата:
|
danik.js, значит в книжке опечатка)
https://yadi.sk/i/IlMM8krQdCoLf https://ru.wikipedia.org/wiki/%D0%9C...%D 0%B8%D1%8F или в википедии опечатка, т.к. запоминание согласно переводчику гугла это memorization от слова memory (насколько я понимаю) https://translate.google.ru/#en/ru/memorization |
Часовой пояс GMT +3, время: 20:10. |
|