繁体   English   中英

列表和 NumPy 数组 memory 大小之间的区别

[英]Difference between list and NumPy array memory size

我听说 Numpy arrays 比 python 内置列表更有效,而且它们在 ZCD69B4957F06CD8DE219D7 中占用的空间更少。 据我了解,Numpy 将这些对象彼此相邻地存储在 memory 中,而列表的 python 实现存储指向给定值的 8 个字节指针。 但是,当我尝试在 jupyter notebook 中进行测试时,结果发现两个对象的大小相同。

import numpy as np
from sys import getsizeof
array = np.array([_ for _ in range(4)])
getsizeof(array), array

返回(128, array([0, 1, 2, 3]))同:

l = list([_ for _ in range(4)])
getsizeof(l), l

给出(128, [0, 1, 2, 3])

你能提供任何明确的例子来说明我如何在 jupyter notebook 中展示它吗?

getsizeof不能很好地衡量 memory 的使用,尤其是列表。 正如您所注意到的,该列表具有指向 memory 中其他地方的对象的指针缓冲区。 getsizeof记录缓冲区的大小,但没有告诉我们有关对象的任何信息。

In [66]: list(range(4))
Out[66]: [0, 1, 2, 3]

该列表有其基本的 object 存储,加上带有 4 个指针的缓冲区(加上一些增长空间)。 这些数字存储在其他地方。 在这种情况下,数字很小,并且已经由解释器创建和缓存。 所以他们的存储不会增加任何东西。 但是每次使用都会创建更大的数字(和浮点数),并占用空间。 列表也可以包含任何内容,例如指向其他列表的指针、字符串或字典,或任何其他内容。

In [67]: arr = np.array([i for i in range(4)])   # via list
In [68]: arr
Out[68]: array([0, 1, 2, 3])
In [69]: np.array(range(4))            # more direct
Out[69]: array([0, 1, 2, 3])
In [70]: np.arange(4)
Out[70]: array([0, 1, 2, 3])           # faster

arr也有一个基本的 object 存储,具有形状和 dtype 等属性。 它也有一个数据缓冲区,但是对于像这样的数字 dtype,该缓冲区具有实际数值(8 字节整数),而不是指向 Python integer 对象的指针。

In [71]: arr.nbytes
Out[71]: 32

该数据缓冲区仅占用 32 个字节 - 4*8。

对于这个小例子, getsizeof返回相同的东西并不奇怪。 基本的 object 存储比存储 4 个值的位置更重要。 当使用 1000 个值和多维 arrays 时,memory 的使用明显不同。

但更重要的是计算速度。 使用数组,您可以执行arr+1arr.sum()类的操作。 它们在编译后的代码中运行,并且速度非常快。 类似的列表操作必须以较慢的 Python 速度进行迭代,尽管指针、获取值等。但是在 arrays 上进行相同类型的迭代甚至更慢。

作为一般规则,如果您从列表开始,并执行append和列表推导等列表操作,最好坚持使用它们。

但是,如果您可以创建一次 arrays,或者从其他 arrays,然后使用numpy方法,您将获得 10 倍的速度提升。 Arrays 确实更快,但前提是您以正确的方式使用它们。 它们不是列表的简单替代品。

NumPy 数组具有关于数组 object header 的一般数组信息(如形状、数据类型等)。 所有值都存储在 memory 的连续块中。 但是列表为每个新的 object 分配新的 memory 块并存储它们的指针。 因此,当您迭代时,您不会直接在 memory 上进行迭代。 您正在迭代指针。 因此,当您处理大数据时,它并不方便。 这是一个例子:

import sys
import numpy as np

random_values_numpy=np.arange(1000)
random_values=range(1000)  
#Numpy
print(random_values_numpy.itemsize)
print(random_values_numpy.size*random_values_numpy.itemsize)  
#PyList
print(sys.getsizeof(random_values))
print(sys.getsizeof(random_values)*len(random_values))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM