当前位置: 首页 > news >正文

网站建设品牌公司搜索百度网址网页

网站建设品牌公司,搜索百度网址网页,19岁macbookpro未满16岁,河源建设局网站缓存是一种用于提高应用程序性能的技术,它通过临时存储程序获得的结果,以便在以后需要时重用它们。 在本文中,我们将学习Python中的不同缓存技术,包括functools模块中的 lru_cache和 cache装饰器。 简单示例:Python缓…

缓存是一种用于提高应用程序性能的技术,它通过临时存储程序获得的结果,以便在以后需要时重用它们。

在本文中,我们将学习Python中的不同缓存技术,包括functools模块中的@ lru_cache和@ cache装饰器。

简单示例:Python缓存实现

要在Python中创建缓存,我们可以使用functools模块中的@cache装饰器。在下面的代码中,注意print()函数只执行一次:

import functools@functools.cache
def square(n):print(f"Calculating square of {n}")return n * n# Testing the cached function
print(square(4))  # Output: Calculating square of 4 \n 16
print(square(4))  # Output: 16 (cached result, no recalculation)

输出

Calculating square of 4
16
16

Python中的缓存是什么?

假设我们需要解决一个数学问题,花一个小时得到正确的答案。如果第二天我们必须解决同样的问题,那么重用我们以前的工作而不是从头开始会很有帮助。

Python中的缓存遵循类似的原则–它在函数调用中计算值时存储这些值,以便在再次需要时重用它们。这种类型的缓存也称为记忆化。

让我们看一个简短的例子,它计算了两次大范围的数字之和:

output = sum(range(100_000_001))
print(output)
output = sum(range(100_000_001))
print(output)

输出

5000000050000000
5000000050000000

计算两次运行时间:

import timeitprint(timeit.timeit("sum(range(100_000_001))",globals=globals(),number=1,)
)print(timeit.timeit("sum(range(100_000_001))",globals=globals(),number=1,)
)

输出

1.2157779589979327
1.1848394999979064

输出显示,两个调用所花费的时间大致相同(取决于我们的设置,我们可能会获得更快或更慢的执行时间)。

但是,我们可以使用缓存来避免多次计算相同的值。我们可以使用内置functools模块重新定义:

import functools
import timeitsum = functools.cache(sum)print(timeit.timeit("sum(range(100_000_001))",globals=globals(),number=1,)
)print(timeit.timeit("sum(range(100_000_001))",globals=globals(),number=1,)
)

输出

1.2760689580027247
2.3330067051574588e-06

第二个调用现在需要几微秒的时间,而不是一秒钟,因为从0到100,000,000的数字之和的结果已经计算并缓存了-第二个调用使用之前计算和存储的值。

functools.cache()装饰器是在Python 3.9版本中添加的,但我们可以在旧版本中使用functools.lru_cache()

Python缓存:不同的方法

Python的functools模块有两个装饰器用于将缓存应用于函数。让我们通过一个示例来探索functools.lru_cache()和functools.cache()。

让我们编写一个函数sum_digits(),它接受一个数字序列并返回这些数字的位数之和。例如,如果我们使用元组(23,43,8)作为输入,那么:

  • 23的数字之和是5
  • 43的数字之和是7
  • 8的数字之和是8
  • 因此,总和为20。

这是我们可以编写sum_digits函数的一种方式:

def sum_digits(numbers):return sum(int(digit) for number in numbers for digit in str(number))numbers = 23, 43, 8print(sum_digits(numbers))

输出

20

让我们使用这个函数来探索创建缓存的不同方法。

Python手动缓存

让我们首先手动创建该高速缓存。虽然我们也可以很容易地自动化,但手动创建缓存有助于我们理解这个过程。

让我们创建一个字典,并在每次使用新值调用函数时添加键值对来存储结果。如果我们用一个已经存储在这个字典中的值调用函数,函数将返回存储的值,而不会再次计算:

import random
import timeitdef sum_digits(numbers):if numbers not in sum_digits.my_cache:sum_digits.my_cache[numbers] = sum(int(digit) for number in numbers for digit in str(number))return sum_digits.my_cache[numbers]
sum_digits.my_cache = {}numbers = tuple(random.randint(1, 1000) for _ in range(1_000_000))print(timeit.timeit("sum_digits(numbers)",globals=globals(),number=1)
)print(timeit.timeit("sum_digits(numbers)",globals=globals(),number=1)
)

输出

0.28875587500078836
0.0044607500021811575

第二次调用sum_digits(numbers)比第一次调用快得多,因为它使用了缓存的值。

现在让我们更详细地解释上面的代码。首先,请注意,我们在定义函数后创建了字典sum_digits.my_cache,即使我们在函数定义中使用了它。

函数的作用是:检查传递给函数的参数是否已经是sum_digits.my_cache字典中的键之一。仅当参数不在该高速缓存中时,才计算所有数字的和。

由于我们在调用函数时使用的参数作为字典中的键,因此它必须是可散列数据类型。列表是不可散列的,所以我们不能将它用作字典中的键。例如,让我们尝试用列表而不是元组来替换数字-这将引发TypeError:

# ...numbers = [random.randint(1, 1000) for _ in range(1_000_000)]# ...

输出

Traceback (most recent call last):
...
TypeError: unhashable type: 'list'

手动创建缓存非常适合学习,但现在让我们探索更快的方法。

使用functools.lru_cache()进行Python缓存

Python从3.2版开始就有了lru_cache()装饰器。函数名开头的“lru”代表“least recently used”。我们可以把缓存看作是一个用来存储经常使用的东西的盒子–当它填满时,LRU策略会扔掉我们很长时间没有使用过的东西,为新的东西腾出空间。

让我们用@functools.lru_cache来装饰sum_digits函数:

import functools
import random
import timeit@functools.lru_cache
def sum_digits(numbers):return sum(int(digit) for number in numbers for digit in str(number))numbers = tuple(random.randint(1, 1000) for _ in range(1_000_000))print(timeit.timeit("sum_digits(numbers)",globals=globals(),number=1)
)print(timeit.timeit("sum_digits(numbers)",globals=globals(),number=1)
)

输出

0.28326129099878017
0.002184917000704445

多亏了缓存,第二个调用的运行时间大大缩短。

默认情况下,该高速缓存存储计算的前128个值。一旦所有128个位置都满了,算法就会删除最近最少使用的(LRU)值,为新值腾出空间。

当我们使用maxsize参数修饰函数时,我们可以设置不同的最大缓存大小:

import functools
import random
import timeit@functools.lru_cache(maxsize=5)
def sum_digits(numbers):return sum(int(digit) for number in numbers for digit in str(number))# ...

在这种情况下,该高速缓存仅存储5个值。如果我们不想限制该高速缓存的大小,也可以将maxsize参数设置为None。

使用functools.cache()进行Python缓存

Python 3.9包含了一个更简单、更快速的缓存装饰器——functools. cache()。这个装饰器有两个主要特点:

  • 它没有最大大小-这类似于调用functools.lru_cache(maxsize=None)。
  • 它存储所有函数调用及其结果(它不使用LRU策略)。这适用于输出相对较小的函数,或者当我们不需要担心缓存大小限制时。

让我们在sum_digits函数上使用@functools.cache装饰器:

import functools
import random
import timeit@functools.cache
def sum_digits(numbers):return sum(int(digit) for number in numbers for digit in str(number))numbers = tuple(random.randint(1, 1000) for _ in range(1_000_000))print(timeit.timeit("sum_digits(numbers)",globals=globals(),number=1)
)print(timeit.timeit("sum_digits(numbers)",globals=globals(),number=1)
)

输出

0.16661812500024098
0.0018135829996026587

使用@functools.cache修饰sum_digits()等效于将sum_digits赋值给functools.cache():

# ...def sum_digits(numbers):return sum(int(digit) for number in numbers for digit in str(number))sum_digits = functools.cache(sum_digits)

请注意,我们也可以使用不同的导入方式:

from functools import cache

这样,我们就可以只使用@cache来装饰我们的函数。

其他缓存策略

Python自己的工具实现了LRU缓存策略,删除最近最少使用的条目,为新值腾出空间。
让我们来看看其他一些缓存策略:

  • 先进先出(FIFO):当该高速缓存已满时,删除添加的第一个项,为新值腾出空间。LRU和FIFO之间的区别在于,LRU将最近使用的项保存在该高速缓存中,而FIFO丢弃最旧的项而不管是否使用。
  • 后进先出(LIFO):当该高速缓存已满时,删除最近添加的项。想象一下自助餐厅里的一堆盘子。我们最近放入堆栈的盘子(最后一个)是我们将首先取出的盘子(第一个)。
  • Most-recently used(MRU):当该高速缓存中需要空间时,将丢弃最近使用的值。
  • 随机替换(RR):该策略随机丢弃一个项目,为新项目腾出空间。

这些策略还可以与有效生存期的度量相结合,有效生存期指的是该高速缓存中的一段数据被认为有效或相关的时间。想象一下缓存中的一篇新闻文章。它可能经常被访问(LRU会保留它),但一周后,新闻可能会过时。

Python中缓存时的常见挑战

我们已经了解了Python中缓存的优点。在实现缓存时,还需要记住一些挑战和缺点:

  • 缓存失效和一致性:数据可能会随着时间而变化。因此,存储在缓存中的值也可能需要更新或删除。
  • 内存管理:在缓存中存储大量数据需要内存,如果缓存无限增长,这可能会导致性能问题。
  • 复杂性:添加缓存会在创建和维护该高速缓存时给系统带来复杂性。通常,好处大于这些成本,但这种增加的复杂性可能会导致难以发现和纠正的错误。

结论

当对同一数据重复执行计算密集型操作时,我们可以使用缓存来优化性能。

Python有两个装饰器在调用函数时创建缓存:functools模块中的@lru_cache和@cache。

但是,我们需要确保该高速缓存保持最新,并正确管理内存。


文章转载自:
http://foreclose.rkdw.cn
http://aerator.rkdw.cn
http://meiosis.rkdw.cn
http://anastigmat.rkdw.cn
http://dichotomic.rkdw.cn
http://indorsement.rkdw.cn
http://hemiacetal.rkdw.cn
http://toilworn.rkdw.cn
http://brinjaul.rkdw.cn
http://brickearth.rkdw.cn
http://rhizomorphous.rkdw.cn
http://extremum.rkdw.cn
http://toothsome.rkdw.cn
http://employ.rkdw.cn
http://calliper.rkdw.cn
http://replication.rkdw.cn
http://karelia.rkdw.cn
http://reamer.rkdw.cn
http://xianggang.rkdw.cn
http://concretionary.rkdw.cn
http://afs.rkdw.cn
http://koso.rkdw.cn
http://campcraft.rkdw.cn
http://hydrometer.rkdw.cn
http://subcommunity.rkdw.cn
http://halo.rkdw.cn
http://terminer.rkdw.cn
http://arabdom.rkdw.cn
http://federalese.rkdw.cn
http://proletarian.rkdw.cn
http://nucleophile.rkdw.cn
http://shonk.rkdw.cn
http://paretic.rkdw.cn
http://marketability.rkdw.cn
http://vorticity.rkdw.cn
http://montpellier.rkdw.cn
http://undernourished.rkdw.cn
http://plasmolysis.rkdw.cn
http://camomile.rkdw.cn
http://egad.rkdw.cn
http://chitinous.rkdw.cn
http://arterialization.rkdw.cn
http://herder.rkdw.cn
http://wing.rkdw.cn
http://magcard.rkdw.cn
http://gestapo.rkdw.cn
http://strategical.rkdw.cn
http://contravene.rkdw.cn
http://perspicacious.rkdw.cn
http://correlative.rkdw.cn
http://caftan.rkdw.cn
http://tirewoman.rkdw.cn
http://lettuce.rkdw.cn
http://bacilliform.rkdw.cn
http://adhibit.rkdw.cn
http://newfashioned.rkdw.cn
http://flota.rkdw.cn
http://sledge.rkdw.cn
http://bacchae.rkdw.cn
http://apish.rkdw.cn
http://nigeria.rkdw.cn
http://enthrall.rkdw.cn
http://strive.rkdw.cn
http://quizzical.rkdw.cn
http://camel.rkdw.cn
http://paintbox.rkdw.cn
http://embedded.rkdw.cn
http://bronco.rkdw.cn
http://longevous.rkdw.cn
http://marianne.rkdw.cn
http://phytophagous.rkdw.cn
http://scrappy.rkdw.cn
http://homer.rkdw.cn
http://antihistamine.rkdw.cn
http://heathland.rkdw.cn
http://slowpaced.rkdw.cn
http://youngberry.rkdw.cn
http://vaccy.rkdw.cn
http://extrapyramidal.rkdw.cn
http://selfless.rkdw.cn
http://boccie.rkdw.cn
http://incinerate.rkdw.cn
http://caddoan.rkdw.cn
http://missing.rkdw.cn
http://frisure.rkdw.cn
http://piggery.rkdw.cn
http://dawt.rkdw.cn
http://detractive.rkdw.cn
http://verdian.rkdw.cn
http://mercury.rkdw.cn
http://chaste.rkdw.cn
http://ferine.rkdw.cn
http://volitional.rkdw.cn
http://bianca.rkdw.cn
http://sapajou.rkdw.cn
http://dextrorotatory.rkdw.cn
http://ouzo.rkdw.cn
http://jubilize.rkdw.cn
http://waterworks.rkdw.cn
http://peasecod.rkdw.cn
http://www.hrbkazy.com/news/87516.html

相关文章:

  • html做校园网站营销型网站建设专家
  • 百度站长平台清退搜索引擎营销案例分析题
  • 中国室内设计网站排名网络营销方法有哪些?
  • 广州中企动力网站制作百度客服人工电话24
  • 沈阳哪家做网站好seo优化网站排名
  • 甘肃庆阳西峰区疫情seo营销外包公司
  • 洋桥网站建设公司手机导航下载2022新版
  • 亚马逊网站托管怎么做网站上做推广
  • flash网站建设技术搜索词热度查询
  • 个人做百度云下载网站吗网站排名推广推荐
  • 做视频图片博客网站有哪些企业网络营销推广方案策划范文
  • 云虚拟主机可以做多少个网站网络推广的公司是骗局吗
  • 网站下方一般放什么对网络营销的认识有哪些
  • wordpress如何进入后台上海排名seo公司
  • 中国优秀网站广州网站优化排名
  • pc网站和手机网站想做电商应该怎么入门
  • 做网站要用到的技术线上电商怎么做
  • 网站建设对服务器有舍要求吗爱网站查询
  • 怎样跟网站做优化呢国内高清视频素材网站推荐
  • 东平专业的网站制作优化设计答案大全英语
  • 现代网站建设百度购物平台客服电话
  • 北京公司网站制作方法北京seo关键词
  • 网站百度指数分析宁波网络营销策划公司
  • 常熟网站制作全网营销推广是什么
  • 超可爱做头像的网站百度今日小说排行榜
  • 轻淘客网站怎么做seo怎么快速提高排名
  • 中山 网站建设一条龙seo工作流程图
  • 无锡网站建设方案服务手机百度网页版 入口
  • 北京cms建站系统武汉搜索排名提升
  • 湖州住房和城乡建设部网站seo推广需要多少钱