缓存函数结果的函数装饰器

编程入门 行业动态 更新时间:2024-10-23 08:24:28
本文介绍了缓存函数结果的函数装饰器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

在 www.mathschallenge 指数范围内(1,101): 打印指数,斐波那契(指数) 这个例子从指数时间跑到接近 瞬间。 但是,这个: 索引在范围(1,101): 打印索引,斐波那契(idx =索引) 这个使用kwargs参数列表,而我''我不知道如何改变我的功能以便将其考虑在内。 有没有人知道如何做到这一点? 解决方案必须将斐波那契(50)和斐波那契(idx = 50)视为同一个调用,从而从缓存中检索第二个。 - Lasse V?gs?ther Karlsen usinglvkblog.blogspot/ mailto:la *** @ vkarlsen.no PGP KeyID: 0x2A42A1C2

解决方案

Lasse V?gs?ther Karlsen写道:

但是,这个: 索引范围(1,101):打印索引,斐波那契( idx = index) 这个使用kwargs参数列表,我不知道如何改变我的功能以考虑到这一点。 有没有人知道如何做到这一点? 解决方案必须将斐波那契(50)和斐波纳契(idx = 50)视为同一个呼叫,从而检索缓存中的第二个。

你的大部分收益来自缓存递归调用,而不是来自缓存 原始调用。 /> 如果解决方案不认为关键字参数等同于位置 参数,它将* * *调用真实函数,然后 递归调用仍然会从缓存中出来,所以最终结果将是b / b 仍然可以提供你想要的几乎所有加速。 除非存储在缓存中的结果是非常大的数据结构,否则我建议您只需将(args,kwargs)存储为缓存键并且 接受有时你会多次缓存同一个电话的命中。

2005年10月8日星期六下午01:53:28 + 0000,Duncan Booth写道:

除非存储在缓存中的结果是非常大的数据结构,否则我建议您只存储(args,kwargs)作为缓存键和

...除了dicts不能是dict键 另一个''memoize''装饰器使用它来获取密钥: kw = kwargs.items() kw.sort() key =(args,tuple(kw)) aspn.activestate /ASPN/Coo.../Recipe/325905 杰夫 -----开始PGP签名 - --- 版本:GnuPG v1.4.1(GNU / Linux) iD8DBQFDR9vXJd01MZaTXX0RAq5 + AJ4yVo8MbputurPvObHBdt urrhZ70gCfUpN2 HxoUEMfpxhkFW3FUDVR + Qkg = = 4UHm -----结束PGP签名-----

怎么不存储args呢?这样的事情: def cache_function(func,args_list): cache = {} def cached_result(* args, ** kwargs): kwargs.update(dict(zip(args_list,args))) 如果缓存中的kwargs: 返回缓存[kwargs] result = func(** kwargs) cache [kwargs] =结果 返回结果 return cached_result args_list是所有参数名称的列表,因此可以将它们转换为关键字参数。

After working through a fair number of the challenges at www.mathschallenge, I noticed that some long-running functions can be helped *a lot* by caching their function results and retrieving from cache instead of calculating again. This means that often I can use a natural recursive implementation instead of unwinding the recursive calls to avoid big exponential running-times. Ok, so I thought, how about creating a decorator that caches the function results and retrieves them from cache if possible, otherwise it calls the function and store the value in the cache for the next invokation. This is what I came up with so far: def cache_function(fn): cache = {} def cached_result(*args, **kwargs): if args in cache: return cache[args] result = fn(*args, **kwargs) cache[args] = result return result return cached_result Example of usage: @cache_function def fibonacci(idx): if idx in (1, 2): return 1 else: return fibonacci(idx-1) + fibonacci(idx-2) for index in range(1, 101): print index, fibonacci(index) this example goes from taking exponential time to run to being near instantaneous. However, this: for index in range(1, 101): print index, fibonacci(idx = index) this one uses the kwargs list of arguments, and I''m not sure how to change my function to take that into account. Does anyone have any clues as to how to do that? The solution would have to consider fibonacci(50) and fibonacci(idx = 50) as the same call and thus retrieve the second one from the cache. -- Lasse V?gs?ther Karlsen usinglvkblog.blogspot/ mailto:la***@vkarlsen.no PGP KeyID: 0x2A42A1C2

解决方案

Lasse V?gs?ther Karlsen wrote:

However, this: for index in range(1, 101): print index, fibonacci(idx = index) this one uses the kwargs list of arguments, and I''m not sure how to change my function to take that into account. Does anyone have any clues as to how to do that? The solution would have to consider fibonacci(50) and fibonacci(idx = 50) as the same call and thus retrieve the second one from the cache.

Most of your gain comes from caching the recursive calls, not from caching the original call. If the solution doesn''t consider keyword arguments equivalent to positional arguments, it will make *one* call to the real function, and then the recursive call will still come out of the cache, so the net result will still be to give you almost all the speedup you wanted. Unless the results stored in the cache are very large data structures, I would suggest that you simply store (args,kwargs) as the cache key and accept the hit that sometime you''ll cache the same call multiple times.

On Sat, Oct 08, 2005 at 01:53:28PM +0000, Duncan Booth wrote:

Unless the results stored in the cache are very large data structures, I would suggest that you simply store (args,kwargs) as the cache key and accept the hit that sometime you''ll cache the same call multiple times.

... except that dicts cannot be dict keys Another ''memoize'' decorator uses this to get the key: kw = kwargs.items() kw.sort() key = (args, tuple(kw)) aspn.activestate/ASPN/Coo.../Recipe/325905 Jeff -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.1 (GNU/Linux) iD8DBQFDR9vXJd01MZaTXX0RAq5+AJ4yVo8MbputurPvObHBdt urrhZ70gCfUpN2 HxoUEMfpxhkFW3FUDVR+Qkg= =4UHm -----END PGP SIGNATURE-----

What about not storing args at all? Something like this: def cache_function(func, args_list): cache = {} def cached_result(*args, **kwargs): kwargs.update(dict(zip(args_list, args))) if kwargs in cache: return cache[kwargs] result = func(**kwargs) cache[kwargs] = result return result return cached_result args_list is a list of all the argument names, so that they can be converted into keyword arguments.

更多推荐

缓存函数结果的函数装饰器

本文发布于:2023-11-01 02:21:29,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1547973.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:函数   缓存

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!