python列表列表占用的内存是预期的10倍
python列表的效率非常低。即使在最简单的情况下,它所需的内存也比具有相同数据的简单列表多10倍。以下代码说明了该问题:python列表列表占用的内存是预期的10倍,python,Python,python列表的效率非常低。即使在最简单的情况下,它所需的内存也比具有相同数据的简单列表多10倍。以下代码说明了该问题: import memory_profiler import sys t=[] m=memory_profiler.memory_usage() t= ["one two three four five" for l in range(60000000)] print ("getsize={} | memory_usage={}".format(sys.getsizeof
import memory_profiler
import sys
t=[]
m=memory_profiler.memory_usage()
t= ["one two three four five" for l in range(60000000)]
print ("getsize={} | memory_usage={}".format(sys.getsizeof(t),memory_profiler.memory_usage()[0]-m[0]))
m=memory_profiler.memory_usage()
t= [["one two three four five"] for l in range(60000000)]
print ("getsize={} | memory_usage={}".format(sys.getsizeof(t),memory_profiler.memory_usage()[0]-m[0]))
import gc
gc.collect()
print ("getsize={} | memory_usage={}".format(sys.getsizeof(t),memory_profiler.memory_usage()[0]-m[0]))
此代码输出如下内容:
getsize=536721616 | memory_usage=459.4375
getsize=536721616 | memory_usage=4181.0703125
getsize=536721616 | memory_usage=4181.0703125
有什么办法可以治愈这种行为吗
使用生成器不是一个选项,我需要内存中的数据供多个工作人员稍后处理。数据必须采用列表列表格式 python中的列表是可调整大小的数组。为了有效地实现list.append,将在列表的实际存储之后预先分配一些内存 元组没有这个问题,它们是不可变的,因此内存分配可以适合实际使用的大小。尝试将[123445]更改为123445,不要忘记,就像我在最初的消息中所做的那样,否则它不是一个元组:内存使用量大幅下降。为了避免我的笔记本电脑的RAM被烧坏,我得到了60万美元: getsize=4826320 | memory_usage=18.94140625 getsize=4826320 | memory_usage=4.2421875 getsize=4826320 | memory_usage=4.2421875 事实上,它低于纯列表实现是令人惊讶的,但我对此没有解释
无论如何,如果您开始担心性能,很可能意味着Python,或者至少Python的本机数据结构不是合适的工具。例如,如果你想操纵矩阵,数字列表将是一个真正的难题,而NumPy的数组将既高效又方便。任何与CPU高效相反的内存高效列表都适合我。问题是是否有这样的事情?你的测量是误导性的。这里每个版本的t只使用一个一二三四五字符串对象;字符串的大小基本上对您的度量没有影响。此外,当您调用gc.collect.sys.getsizeoft时,t显然仍然是可访问的。它只计算列表本身,作为一个容器,基本上是60000000个指针,有一些开销,您需要将字符串的大小相加,然后,在没有更多信息的情况下,整个内存使用次数将匹配,写入磁盘,考虑缓冲或重构管道与发电机一起工作。一个2345不是元组;括号里只有一二三四五。一二三四五,是长度为1的元组。抢手货但令人惊讶的是,添加逗号会进一步减少内存使用;窥视孔优化器已经预计算了元组,并且一个元组对象正用于所有列表条目。另外,请注意问题中的代码是打印内存使用情况的差异,而不是实际内存使用情况;例如,第二次内存使用率打印的小而正的值表示进程内存消耗的小幅度增加。它不会在第二次打印后重置m,因此第三次打印并不意味着内存使用量再次增加。如果您想查看6000万元组的内存使用情况,可以将字符串保存到一个变量中,然后使用变量x='one-two…'构建元组:x='one-two…',然后是x,以构建元组。优化器当前无法对其进行优化。