列表的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(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
有没有办法治愈这种行为?
使用生成器不是一个选项,我需要内存中的数据供以后由多个工作人员处理。数据必须是列表格式列表。
答案 0 :(得分:0)
python中的列表是可调整大小的数组。为了实现list.append()
的有效实现,在列表的实际存储之后会预先分配一些内存。
元组没有这个问题,它们是不可变的,因此内存分配可以适合实际使用的大小。尝试将["one two three four five"]
更改为("one two three four five",)
(不要像我在原始邮件中那样忘记,
,否则它不是元组):内存使用率大幅下降。我得到(600000以避免吹掉笔记本电脑的RAM):
getsize=4826320 | memory_usage=18.94140625 getsize=4826320 | memory_usage=4.2421875 getsize=4826320 | memory_usage=4.2421875
实际上令人惊讶的是它低于普通列表实现,但我没有解释!
无论如何,如果你开始担心性能,很可能意味着Python,或者至少Python的本机数据结构不是正确的工具。例如,如果你想操纵矩阵,数字列表列表将是一个真正的痛苦,而NumPy的数组将既高效又方便。