【发布时间】:2019-12-09 18:21:46
【问题描述】:
我试图了解 Python 对象使用了多少内存。
在下面的代码中,我检查了 numpy 数组与列表以及下标 numpy 数组的内存:
import sys, os, psutil, numpy as np
def size_of(obj):
return f'{sys.getsizeof(obj) / 1000000:,.0f} MB'
def get_memory_usage():
process = psutil.Process(os.getpid())
return f'{process.memory_info().rss / 1000000:,.0f} MB'
# Numpy vs List
print(f'(1) Mem usage: {get_memory_usage()}')
ONE_HUNDRED_MIL_NP = np.random.randint(-128,127,int(10**8),dtype='int8')
print(f'(2) Mem usage: {get_memory_usage()}, ONE_HUNDRED_MIL_NP: {size_of(ONE_HUNDRED_MIL_NP)}')
ONE_HUNDRED_MIL_LIST = list(np.random.choice(127, int(10**8), replace=True).astype('int8'))
print(f'(3) Mem usage: {get_memory_usage()}, ONE_HUNDRED_MIL_LIST: {size_of(ONE_HUNDRED_MIL_LIST)}')
# Now try subscriping
FOURCOLS = np.random.randint(-128,127,size=(int(10**8),4),dtype='int8')
print(f'(4) Mem usage: {get_memory_usage()}, FOURCOLS: {size_of(FOURCOLS)}')
FOURCOLS_PERMUTED = FOURCOLS[np.random.randint(0,len(FOURCOLS),size=len(FOURCOLS),dtype='int32')]
print(f'(5) Mem usage: {get_memory_usage()}, FOURCOLS_PERMUTED: {size_of(FOURCOLS_PERMUTED)}')
这会返回:
(1) Mem usage: 187 MB
(2) Mem usage: 287 MB, ONE_HUNDRED_MIL_NP: 100 MB
(3) Mem usage: 3,526 MB, ONE_HUNDRED_MIL_LIST: 900 MB
(4) Mem usage: 3,926 MB, FOURCOLS: 400 MB
(5) Mem usage: 4,326 MB, FOURCOLS_PERMUTED: 400 MB
注意事项:
- 输出 (2) 有意义。一个 int8 是 8 位(一个字节),一亿字节是 100 MB
- 输出 (3) 我不明白:
- 第一个问题是 sys.getsizeof() 显示对象占用了 900 MB,但 psutil 显示该进程现在占用了 3,239 MB 以上的内存 (3526-287=3239)。这种幻像内存使用量来自哪里?
- 900 MB 从何而来? (从Python: Size of Reference? 开始,我假设有 100 MB 的 numpy 对象加上 1 亿个指针,每个指针有 8 个字节,所以 100 MB + 800 MB = 900 MB?)
- 输出 (4) 有意义。 4 亿个 int8 为 400 MB。
- 输出 (5) 我不明白。是复制还是参考?如果引用,我们只引用 1 亿行,对吗?这怎么会变成 400 MB?
谢谢
【问题讨论】:
-
搜索
[numpy] getsizeof以查看以前的讨论。如果您不了解数组和列表的存储方式,这种测试可能会令人困惑。getsizeof在应用于 numpy 数组时有些用处——前提是您了解copy和view之间的区别。查找列表时没用。
标签: python-3.x numpy memory profiling