减少Python对象大小的技巧
与 C 或 C++ 等编程语言相比,我们都知道Python的一个非常普遍的缺点。由于Python对象会消耗大量内存,因此速度要慢得多,并且不太适合执行内存密集型任务。在处理某些任务时,这可能会导致内存问题。当 RAM 在执行期间因任务而过载并且程序开始冻结或行为不自然时,我们将其称为内存问题。
让我们看看我们可以有效地使用此内存并减小对象大小的一些方法。
使用内置字典:
我们都非常熟悉Python中的字典数据类型。这是一种以键和值的形式存储数据的方式。但是在内存管理方面,字典并不是最好的。事实上,这是最糟糕的。让我们看一个例子:
# importing the sys library
import sys
Coordinates = {'x':3, 'y':0, 'z':1}
print(sys.getsizeof(Coordinates))
288
我们看到数据类型字典的一个实例占用 288 个字节。因此,当我们有很多实例时,它将消耗大量内存:
因此,我们得出结论,在处理内存效率高的程序时,字典不适合。
使用元组:
元组非常适合存储不可变数据值,并且与字典相比在减少内存使用方面也非常有效:
import sys
Coordinates = (3, 0, 1)
print(sys.getsizeof(Coordinates))
72
为简单起见,我们假设索引0、1、2分别代表x、y、z 。所以从 288 字节,我们只使用元组而不是字典就可以减少到 72 字节。仍然不是很有效。如果我们有大量实例,我们仍然需要大量内存:
使用类:
通过将代码安排在类中,与使用字典和元组相比,我们可以显着减少内存消耗。
import sys
class Point:
# defining the coordinate variables
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
Coordinates = Point(3, 0, 1)
print(sys.getsizeof(Coordinates))
56
我们看到同一个程序现在需要 56 个字节,而不是之前的 72 个字节。变量 x、y 和 z 各消耗 8 个字节,而其余 32 个字节由Python的内部代码消耗。如果我们有更多的实例,我们有以下分布 -
因此我们得出结论,在节省内存方面,类比字典和元组更有优势。
旁注:函数sys.getsizeof(object[, default]) 规范说:“只考虑直接归因于对象的内存消耗,而不考虑它所引用的对象的内存消耗。”
所以在你的例子中:
class Point:
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
Coordinates = Point(3, 0, 1)
对象坐标的有效内存使用量为:
sys.getsizeof(坐标) +
sys.getsizeof(Coordinates.x) +
sys.getsizeof(Coordinates.y) +
sys.getsizeof(坐标.z) =
= 56 + 28 + 24 + 28 =
= 136
请参考 https://docs。 Python.org/3/library/sys.html。
使用记录类:
Recordclass
是一个相当新的Python库。它支持记录类型,这不是Python内置的。由于recordclass
是 MIT 许可的第三方模块,我们需要先在终端中输入以下内容来安装它:
pip install recordclass
让我们使用recordclass
来看看它是否进一步有助于减少内存大小。
# importing the installed library
import sys
from recordclass import recordclass
Point = recordclass('Point', ('x', 'y', 'z'))
Coordinates = Point(3, 0, 1)
print(sys.getsizeof(Coordinates))
输出:
48
所以使用recordclass
进一步将一个实例所需的内存从56字节减少到48字节。如果我们有大量实例,这将是分布:
使用数据对象:
在前面的示例中,在使用recordclass
时,即使是垃圾值也会被收集,从而浪费了不必要的内存。这意味着仍有优化的范围。这正是使用数据对象的原因。数据对象功能属于 recordclass 模块,其特点是它不会产生任何垃圾值。
import sys
from recordclass import make_dataclass
Position = make_dataclass('Position', ('x', 'y', 'z'))
Coordinates = Position(3, 0, 1)
print(sys.getsizeof(Coordinates))
输出:
40
最后,我们看到大小从每个实例 48 字节减少到每个实例 40 字节。因此,我们看到在内存利用率最低的情况下,数据对象是组织代码的最有效方式。