改进方案
- 使用
__slots__
:
- 在类中定义
__slots__
来限制实例能够拥有的属性。因为默认情况下,Python 实例使用字典来存储属性,这会占用较多内存。而 __slots__
可以使用更紧凑的方式存储属性,从而减少内存占用,在频繁实例化时提升性能。
- 重构后的代码如下:
class Rectangle:
__slots__ = ('width', 'height')
def __init__(self, width, height):
self.width = width
self.height = height
def calculate_area(self):
return self.width * self.height
def calculate_perimeter(self):
return 2 * (self.width + self.height)
- 缓存属性值(如果适用):
- 如果
width
和 height
的值在实例的生命周期内不会改变,并且 calculate_area
和 calculate_perimeter
方法会被频繁调用,可以在 __init__
方法中预先计算并缓存面积和周长。这样在调用相应方法时,直接返回缓存的值,减少计算开销。
- 重构后的代码如下:
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
self._area = self.width * self.height
self._perimeter = 2 * (self.width + self.height)
def calculate_area(self):
return self._area
def calculate_perimeter(self):
return self._perimeter
- 考虑使用
namedtuple
(如果对象是不可变的):
- 如果
Rectangle
对象的 width
和 height
在创建后不需要改变,namedtuple
是一个很好的选择。namedtuple
是不可变的,并且比普通类更轻量级,占用内存更少,创建速度更快。
- 代码如下:
from collections import namedtuple
Rectangle = namedtuple('Rectangle', ['width', 'height'])
def calculate_area(rect):
return rect.width * rect.height
def calculate_perimeter(rect):
return 2 * (rect.width + rect.height)
原因解释
__slots__
:
- 减少内存占用,因为每个实例不再需要一个字典来存储属性。这对于频繁实例化的类来说,可以显著减少内存开销,提高内存使用效率,进而提升性能。
- 缓存属性值:
- 对于频繁调用的计算方法,避免了重复计算,直接返回预先计算好的值,从而提高了方法的调用速度,提升整体性能。
namedtuple
:
- 由于其不可变性和轻量级特性,创建
namedtuple
实例比创建普通类实例更快,并且占用更少的内存。适用于对象状态不会改变的场景,进一步优化了频繁实例化的性能。