gpt4 book ai didi

python - 如何在 python 中处理 cpu 缓存(或调用一次函数的最快方法)

转载 作者:太空宇宙 更新时间:2023-11-04 01:02:46 28 4
gpt4 key购买 nike

我发现 python 的 VM 似乎对 CPU-Cache 非常不友好。

例如:

import time
a = range(500)

sum(a)

for i in range(1000000): #just to create a time interval, seems this disturb cpu cache?
pass


st = time.time()
sum(a)
print (time.time() - st)*1e6

时间:

> 100us

另一种情况:

import time
a = range(500)

for i in range(100000):
st = time.time()
sum(a)
print (time.time() - st)*1e6

时间:

~ 20us

我们可以看到,当频繁运行时,代码会变得更快。

有解决办法吗?

可以引用这个问题:(应该是同一个问题) python function(or a code block) runs much slower with a time interval in a loop

我觉得这道题很难。想必对python虚拟机、c和cpu-cache的机制有深入的了解。

对于将此问题发布到哪里以获得可能的答案,您有什么建议吗?

最佳答案

您的假设“我们可以看到,当频繁运行时,代码变得更快”不太正确。

这个循环

#just to create a time interval, seems this disturb cpu cache?
for i in range(1000000):
pass

不仅仅是一个简单的时间延迟。在 Python 2 中,它创建一个包含 1,000,000 个整数对象的列表,对其进行循环,然后将其销毁。在 Python 3 中,range() 是一个生成器,因此它不会浪费内存; Python 2 等效项是 xrange()

在标准的 CPython 实现中,列表是指向它包含的对象的指针数组。在32位系统上,一个整型对象占12个字节,一个空列表对象占32个字节,当然还有一个指针占4个字节。所以 range(1000000) 一共消耗了 32 + 1000000 * (4 + 12) = 16000032 字节。

一旦循环结束,range() 列表上的引用计数就会降为零,因此它及其内容符合垃圾回收条件。垃圾收集一百万个整数需要一点时间,因此您注意到循环结束后出现时间延迟也就不足为奇了。此外,创建和释放所有这些对象的过程通常会导致一些内存碎片,这将影响后续代码的效率。

FWIW,在我的 2GHz Pentium 4 Linux 系统上,您的第一个代码块打印 38 - 41µs 范围内的值,但如果我将循环更改为使用 xrange(),则时间会下降到 31 - 34µs。

如果代码被修改以防止 range() 的垃圾回收直到 sum(a) 被计算,那么我们是否在时间上几乎没有区别使用 range()xrange()

import time

a = range(500)
sum(a)

bigrange = xrange(1000000)

for i in bigrange:
pass

st = time.time()
sum(a)
print (time.time() - st) * 1e6

#Maintain a reference to bigrange to prevent it
#being garbage collected earlier
print sum(bigrange)

关于python - 如何在 python 中处理 cpu 缓存(或调用一次函数的最快方法),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32163585/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com