如何在python中对内存访问进行去优化?

如何在python中对内存访问进行去优化?,python,memory,Python,Memory,这可能没有用。这只是我为自己设定的一个挑战 假设你有一个大数组。如何才能使程序不受益于缓存、缓存线预取或只有在第一次访问完成后才能确定下一次内存访问这一事实 所以我们有了我们的阵列: array=[0]*10000000 如果必须访问一个循环中的所有元素,那么最好的方法是什么?其想法是尽可能地增加每个内存位置的访问时间 我不是在寻找一种解决方案,它建议在进行下一次访问之前做“其他事情”(这需要时间)。这个想法实际上是尽可能地增加访问时间。我想我们必须以某种方式遍历数组(可能是随机的?我还在研究它

这可能没有用。这只是我为自己设定的一个挑战

假设你有一个大数组。如何才能使程序不受益于缓存、缓存线预取或只有在第一次访问完成后才能确定下一次内存访问这一事实

所以我们有了我们的阵列:

array=[0]*10000000

如果必须访问一个循环中的所有元素,那么最好的方法是什么?其想法是尽可能地增加每个内存位置的访问时间


我不是在寻找一种解决方案,它建议在进行下一次访问之前做“其他事情”(这需要时间)。这个想法实际上是尽可能地增加访问时间。我想我们必须以某种方式遍历数组(可能是随机的?我还在研究它)

Python实习生小整数。使用大于255的整数<代码>*仅在展开时添加对列表中已有数字的引用,请改用唯一值。缓存讨厌随机性,所以选择随机

import random
array = list(range(256, 10000256))
while array:
    array.pop(random.randint(0, len(array)-1))
关于小整数的一个注记。当您在程序中创建一个整数时,比如说
12345
,python会在55字节或更大字节的堆上创建一个对象。这个很贵。因此,(我认为)-4和255之间的数字被内置到python中,以优化常见的小数字操作。通过避免这些数字,您可以强制python在堆上分配整数,从而分散将要接触的内存量并降低缓存效率


如果在数组中使用单个数字
[1234]*100000
,则会多次引用该单个数字。如果使用唯一的数字,则它们都在堆上单独分配,从而增加内存占用。当它们从列表中删除时,python必须触摸对象以减少其引用计数,这会将其内存位置拉入缓存,从而使其他内容无效。

我没想到会有任何区别,但事实上,以随机顺序访问数字要比以顺序或相反顺序访问数字慢得多(两者大致相同)

这似乎真的是随机性。只是无序地访问索引,但使用一种模式,例如
[0,N-1,2,N-3,…]
[0,N/2,1,N/2+1,…]
,与按顺序访问索引一样快:

>>> alt1 = [i if i % 2 == 0 else N - i for i in range(N)]
>>> alt2 = [i for p in zip(srt[:N//2], srt[N//2:]) for i in p]
>>> %timeit sum(arr[i] for i in alt1)
10 loops, best of 5: 24.5 ms per loop
>>> %timeit sum(arr[i] for i in alt2)
10 loops, best of 5: 24.1 ms per loop
有趣的是,只需迭代无序索引(并像上面的数组一样计算它们的
)也比对排序索引执行相同操作慢,但没有那么多。在
srt
rnd
之间约35毫秒的差异中,约10毫秒似乎来自于对随机索引的迭代,约25毫秒来自于以随机顺序实际访问索引

>>> %timeit sum(i for i in srt)
100 loops, best of 5: 19.7 ms per loop
>>> %timeit sum(i for i in rnd)
10 loops, best of 5: 30.5 ms per loop
>>> %timeit sum(arr[i] for i in srt)
10 loops, best of 5: 24.5 ms per loop
>>> %timeit sum(arr[i] for i in rnd)
10 loops, best of 5: 56 ms per loop

(在一台运行Linux的老式笔记本电脑上,IPython 5.8.0/Python 3.7.3)

那么你想放慢速度
array[…]
?既然不允许“做其他事情”,那么什么是允许的?另外,你这里说的是纯
array[k]
而不是
array.pop(k)
array[:]k]
,对吗?很抱歉我不够清晰。是的,我想减慢数组[k]的速度,其中k是索引(或内存地址)。我所说的“如果不允许做其他事情”,是什么意思,我想说的是,您不能运行另一个需要时间的函数。我想减慢的是访问速度,而不是试图插入另一个函数或其他需要时间的东西。为什么“Python实习生小整数。使用整数>255。*只需在展开时添加对列表中已存在数字的引用,改用唯一值”“我不太明白为什么我们需要它。python实习小整数是什么意思?”克里斯补充道。
>>> %timeit sum(i for i in srt)
100 loops, best of 5: 19.7 ms per loop
>>> %timeit sum(i for i in rnd)
10 loops, best of 5: 30.5 ms per loop
>>> %timeit sum(arr[i] for i in srt)
10 loops, best of 5: 24.5 ms per loop
>>> %timeit sum(arr[i] for i in rnd)
10 loops, best of 5: 56 ms per loop