如何结合@singledispatch 和@lru_cache?
How to combine @singledispatch and @lru_cache?
我有一个 Python 单分派通用函数,如下所示:
@singledispatch
def cluster(documents, n_clusters=8, min_docs=None, depth=2):
...
重载是这样的:
@cluster.register(QuerySet)
@lru_cache(maxsize=512)
def _(documents, *args, **kwargs):
...
第二个基本上是预处理一个 QuerySet
对象并调用通用的 cluster()
函数。
一个QuerySet is a Django object,但是那个不应该在这里起作用;除了它是可散列的并且因此可以与 lru_cache
.
一起使用的事实之外
通用函数无法缓存,因为它接受不可散列的对象(例如列表)作为参数。但是,可以缓存重载函数,因为 QuerySet
对象是可散列的。这就是我添加 @lru_cache()
注释的原因。
但是,缓存似乎没有被应用:
qs: QuerySet = [...]
start = datetime.now(); cluster(Document.objects.all()); print(datetime.now() - start)
0:00:02.629259
我希望在一个实例中发生相同的调用,但是:
start = datetime.now(); cluster(Document.objects.all()); print(datetime.now() - start)
0:00:02.468675
缓存统计信息证实了这一点:
cluster.registry[django.db.models.query.QuerySet].cache_info()
CacheInfo(hits=0, misses=2, maxsize=512, currsize=2)
更改 @lru_cache
和 @.register
注释的顺序似乎没有什么不同。
类似,但答案不符合个人功能层面。
甚至可以在这个级别上将这两个注释组合起来吗?如果是,怎么做?
hash(Document.objects.all()) == hash(Document.objects.all())
与 Django QuerySet
.
不一致
在返回的 QuerySet
被评估之前,调用 Document.objects.all()
不会访问数据库。
Pickling is usually used as a precursor to caching
根据您的用例,您可以尝试缓存 QuerySet
或其 query
属性的 pickle。
@cluster.register(bytes)
@lru_cache(maxsize=512)
def _(documents, *args, **kwargs):
documents = pickle.loads(documents)
...
cluster(pickle.dumps(Document.objects.all()))
或
cluster(pickle.dumps(Document.objects.all().query))
我有一个 Python 单分派通用函数,如下所示:
@singledispatch
def cluster(documents, n_clusters=8, min_docs=None, depth=2):
...
重载是这样的:
@cluster.register(QuerySet)
@lru_cache(maxsize=512)
def _(documents, *args, **kwargs):
...
第二个基本上是预处理一个 QuerySet
对象并调用通用的 cluster()
函数。
一个QuerySet is a Django object,但是那个不应该在这里起作用;除了它是可散列的并且因此可以与 lru_cache
.
通用函数无法缓存,因为它接受不可散列的对象(例如列表)作为参数。但是,可以缓存重载函数,因为 QuerySet
对象是可散列的。这就是我添加 @lru_cache()
注释的原因。
但是,缓存似乎没有被应用:
qs: QuerySet = [...]
start = datetime.now(); cluster(Document.objects.all()); print(datetime.now() - start)
0:00:02.629259
我希望在一个实例中发生相同的调用,但是:
start = datetime.now(); cluster(Document.objects.all()); print(datetime.now() - start)
0:00:02.468675
缓存统计信息证实了这一点:
cluster.registry[django.db.models.query.QuerySet].cache_info()
CacheInfo(hits=0, misses=2, maxsize=512, currsize=2)
更改 @lru_cache
和 @.register
注释的顺序似乎没有什么不同。
甚至可以在这个级别上将这两个注释组合起来吗?如果是,怎么做?
hash(Document.objects.all()) == hash(Document.objects.all())
与 Django QuerySet
.
在返回的 QuerySet
被评估之前,调用 Document.objects.all()
不会访问数据库。
Pickling is usually used as a precursor to caching
根据您的用例,您可以尝试缓存 QuerySet
或其 query
属性的 pickle。
@cluster.register(bytes)
@lru_cache(maxsize=512)
def _(documents, *args, **kwargs):
documents = pickle.loads(documents)
...
cluster(pickle.dumps(Document.objects.all()))
或
cluster(pickle.dumps(Document.objects.all().query))