|
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, время: 13:12. |
|