python中的cachetools用法详解(Cached、LRUCache、TTLCache、LFUCache、RRCache)

首先安装模块:

pip install cachetools

Cachetools提供了五个主要功能:

  • Cached
  • LRUCache
  • TTLCache
  • LFUCache
  • RRCache

Cached

        cached用作装饰器。当我们调用缓存时,它会将函数缓存起来以备后用。默认情况下,这将执行一个简单的缓存。

语法结构:

@cached(cache = {})
def some_fun():
    pass

示例代码:  【使用时间模块来查看模块的效率】

from cachetools import cached
import time


# without cached
def fib(n):
    return n if n < 2 else fib(n - 1) + fib(n - 2)


s = time.time()
print(fib(36))
print("Time Taken:", time.time() - s)

# Now using cached
s = time.time()


# Use this decorator to enable caching
@cached(cache={})
def fib(n):
    return n if n < 2 else fib(n - 1) + fib(n - 2)


print(fib(36))
print("Time Taken(cached): ", time.time() - s)

运行结果:

LRUCache

        LRUCache在缓存装饰器内部使用。LRU 缓存是指“最近最少使用”的缓存。它接受一个参数“maxsize”,该参数说明应如何缓存最近的函数。

语法结构:

@cached(cache= LRUCache(maxsize= 3))
def some_fun():
    pass

示例代码:

from cachetools import cached, LRUCache
import time


# cache using LRUCache
@cached(cache=LRUCache(maxsize=3))
def my_fun(n):
    # This delay resembles some task
    s = time.time()
    time.sleep(n)
    print("\nTime Taken: ", time.time() - s)
    return f"I am executed: {n}"


# Takes 3 seconds
print(my_fun(3))

# Takes no time
print(my_fun(3))

# Takes 2 seconds
print(my_fun(2))

# Takes 1 second
print(my_fun(1))

# Takes 4 seconds
print(my_fun(4))

# Takes no time
print(my_fun(1))

# Takes 3 seconds because maxsize = 3
# and the 3 recent used functions had 1,
# 2 and 4.
print(my_fun(3))

运行结果:

注意 LRUCache也可以从标准 Python 包 functools 中调用

from functools import lru_cache
@lru_cache
def myfunc():
    pass

TTLCache

        TTLCache或“Time To Live”缓存是 cachetools 模块中包含的第三个功能。它有两个参数——“maxsize”和“TTL”。“maxsize”的使用与 LRUCache 相同,但这里的“TTL”值表示缓存应存储多长时间。该值以秒为单位。

语法结构:

@cached(cache= TTLCache(maxsize= 33, ttl = 600))
def some_fun():
    pass

        在 @cached(cache=TTLCache(maxsize=33, ttl=600)) 中,maxsize 和 ttl 是 TTLCache 类的两个参数,用于设置缓存的最大大小和过期时间。

  • maxsize:表示缓存的最大大小。这可以帮助限制缓存的大小,防止过多的条目占用内存。在这个例子中,maxsize=33 表示缓存的最大条目数量为 33。实际上,TTLCache 不会覆盖旧的结果,而是会按照 LRU(最近最少使用)算法删除最久未使用的条目,以腾出空间来存储新的条目。这就意味着当缓存达到最大大小 maxsize 时,新的结果会替换掉最久未使用的结果。如果不指定 maxsize,则缓存大小不受限制。
  • ttl:表示缓存的过期时间,即缓存中的结果可以保存多长时间。当结果的存活时间超过 ttl 时,缓存会自动删除该结果。如果不指定 ttl,则缓存中的结果永远不会过期。如果你希望缓存条目永久保存,可以将 ttl 参数设置为一个较大的值,比如设置为 ttl=float('inf'),表示缓存条目永不过期。这样就可以实现持久化的缓存效果。

示例代码:

from cachetools import cached, TTLCache
import time


# Here recent 32 functions
# will we stored for 1 minutes
@cached(cache=TTLCache(maxsize=32, ttl=25))
def my_fun(n):
    # This delay resembles some task
    s = time.time()
    time.sleep(n)
    print("\nTime Taken: ", time.time() - s)
    return f"I am executed: {n}"


print(my_fun(3))
print(my_fun(3))
print("*" * 100)

time.sleep(24)
print(my_fun(3))
print("*" * 100)

time.sleep(26)
print(my_fun(3))

运行结果:

@cached()中lock参数的用法

在 @cached() 装饰器中,lock 参数用于控制多线程或多进程环境下的并发访问。

默认情况下,@cached() 使用一个简单的互斥锁(mutex lock)来保护缓存的并发访问。这意味着在同一时间只能有一个线程或进程可以访问缓存,在其他线程或进程完成访问之前,所有其他的访问请求都会被阻塞。

你可以通过将 lock 参数设置为一个自定义的锁对象来改变默认行为。自定义的锁对象必须实现 acquire() 和 release() 方法,以便在访问缓存时进行加锁和解锁操作。这样可以更灵活地控制并发访问的行为。

示例代码:

import time
import threading
from cachetools import cached, TTLCache

custom_lock = threading.Lock()


@cached(cache=TTLCache(maxsize=10, ttl=20), lock=custom_lock)
def slow_calculation(n):
    print(f"Performing slow calculation for {n}...")
    start_time = time.time()
    nn = n
    i = 0
    while i < 10000:
        time.sleep(0.01)
        n += i
        i += 1
    end_time = time.time()
    print(f"{nn}线程耗时:{end_time - start_time}")
    return n


@cached(cache=TTLCache(maxsize=10, ttl=20))
def slow_calculation2(n):
    print(f"Performing slow calculation for {n}...")
    start_time = time.time()
    nn = n
    i = 0
    while i < 10000:
        time.sleep(0.01)
        n += i
        i += 1
    end_time = time.time()
    print(f"{nn}线程耗时:{end_time - start_time}")
    return n


def task(n):
    ret = slow_calculation(n)
    print(f"{n}线程执行结果ret:{ret}")
    ret2 = slow_calculation2(n)
    print(f"{n}线程执行结果ret2:{ret2}")
    print(f"{n}线程执行结果ret1:{ret},ret2:{ret2}")


def run_threads():
    threads = []
    for i in range(5):
        t = threading.Thread(target=task, args=(i,))
        threads.append(t)
        t.start()

    for t in threads:
        t.join()


run_threads()

运行结果:

LFUCache

        LFUCache或“Least Frequently Used”缓存是另一种类型的缓存技术,用于检索项目被调用的频率。它会在必要时丢弃最不常调用的项目以腾出空间。它采用一个参数——“maxsize”,与 LRUCache 中的相同。

语法结构:

@cached(cache= LFUCache(maxsize= 33))
def some_fun():
    pass

示例代码:

from cachetools import cached, LFUCache
import time


# Here if a particular item is not called
# within 5 successive call of the function,
# it will be discarded
@cached(cache=LFUCache(maxsize=5))
def my_fun(n):
    # This delay resembles some task
    s = time.time()
    time.sleep(n)
    print("\nTime Taken: ", time.time() - s)
    return f"I am executed: {n}"


print(my_fun(3))
print(my_fun(3))
print(my_fun(2))
print(my_fun(4))
print(my_fun(1))
print(my_fun(1))
print(my_fun(3))
print(my_fun(3))
print(my_fun(4))

运行结果:

RRCache

        RRCache或“Random Replacement”缓存是另一种缓存技术,它随机选择缓存中的项目并在必要时丢弃它们以释放空间。它采用一个参数——“maxsize”,与 LRUCache 中的相同。它还有一个参数选择,默认设置为“random.choice”。

语法结构:

@cached(cache= RRCache(maxsize= 33))
def some_fun():
    pass

示例代码:

from cachetools import cached, RRCache
import time


# Here if a particular item is not called
# within 5 successive call of the function,
# it will be discarded
@cached(cache=RRCache(maxsize=5))
def my_fun(n):
    # This delay resembles some task
    s = time.time()
    time.sleep(n)
    print("\nTime Taken: ", time.time() - s)
    return f"I am executed: {n}"


print(my_fun(3))
print(my_fun(3))
print(my_fun(2))
print(my_fun(4))
print(my_fun(1))
print(my_fun(1))
print(my_fun(3))
print(my_fun(2))
print(my_fun(3))

运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值