如何通过自动获取和释放对象池来减少构造函数的开销?
How to decrease the constructor overhead by automatic acquisition and release from an object pool?
我在 Python 中创建了一个不可变数据类型,每秒创建和释放数百万个对象。彻底分析代码后,看起来大部分时间都花在了构造函数上。
我想到的解决方案是使用对象池,这样引用计数和内存分配就一次性完成了。我看过像 this 这样的解决方案,其中需要显式调用 acquire
和 release
方法。
然而,我实现的class类似于Python中的Decimal
class,其中对象由numpy
自动创建和释放。例如,使用我的 class 的一小段代码将如下所示(我使用 Decimal 而不是我自己的 class):
import numpy as np
from decimal import Decimal
x = np.array([[Decimal(1), Decimal(2)], [Decimal(3), Decimal(4)]]
y = np.array([[Decimal(5), Decimal(6)], [Decimal(7), Decimal(8)]]
z = (x * y) + (2 * x) - (y ** 2) + (x ** 3)
因为 class 是不可变的,numpy 需要为每个操作创建一个新对象,这会减慢整个代码的速度。此外,因为 numpy
是创建这些对象的代码,所以我不认为我可以显式调用 acquire
或 release
.
等方法
是否有更好的对象池或其他方法来一次性创建大量对象,然后释放的对象自动放回池中?换句话说,有没有其他解决方案可以避免频繁创建和销毁对象?
P.S。我知道这不是使用 numpy
的好方法。这是我设计的第一步,希望 numpy
能在接下来的步骤中更有效地使用。
这样的东西行得通吗?
class Pool():
def __init__(self, type_, extra_alloc=1):
self._objects = []
self.type = type_
self.extra_alloc = extra_alloc
def allocate(self, size):
self._objects.extend(object.__new__(self.type) for _ in range(size))
def get_obj(self):
print("Getting object")
if not self._objects:
self.allocate(self.extra_alloc)
return self._objects.pop()
def give_obj(self, obj):
print("Object released")
self._objects.append(obj)
class Thing(): # This can also be used as a base class
pool = None
def __new__(self, *args):
return self.pool.get_obj()
def __del__(self):
self.pool.give_obj(self)
thing_pool = Pool(Thing)
Thing.pool = thing_pool
Thing()
# Getting object
# Object released
x = Thing()
# Getting object
del x
# Object released
我在 Python 中创建了一个不可变数据类型,每秒创建和释放数百万个对象。彻底分析代码后,看起来大部分时间都花在了构造函数上。
我想到的解决方案是使用对象池,这样引用计数和内存分配就一次性完成了。我看过像 this 这样的解决方案,其中需要显式调用 acquire
和 release
方法。
然而,我实现的class类似于Python中的Decimal
class,其中对象由numpy
自动创建和释放。例如,使用我的 class 的一小段代码将如下所示(我使用 Decimal 而不是我自己的 class):
import numpy as np
from decimal import Decimal
x = np.array([[Decimal(1), Decimal(2)], [Decimal(3), Decimal(4)]]
y = np.array([[Decimal(5), Decimal(6)], [Decimal(7), Decimal(8)]]
z = (x * y) + (2 * x) - (y ** 2) + (x ** 3)
因为 class 是不可变的,numpy 需要为每个操作创建一个新对象,这会减慢整个代码的速度。此外,因为 numpy
是创建这些对象的代码,所以我不认为我可以显式调用 acquire
或 release
.
是否有更好的对象池或其他方法来一次性创建大量对象,然后释放的对象自动放回池中?换句话说,有没有其他解决方案可以避免频繁创建和销毁对象?
P.S。我知道这不是使用 numpy
的好方法。这是我设计的第一步,希望 numpy
能在接下来的步骤中更有效地使用。
这样的东西行得通吗?
class Pool():
def __init__(self, type_, extra_alloc=1):
self._objects = []
self.type = type_
self.extra_alloc = extra_alloc
def allocate(self, size):
self._objects.extend(object.__new__(self.type) for _ in range(size))
def get_obj(self):
print("Getting object")
if not self._objects:
self.allocate(self.extra_alloc)
return self._objects.pop()
def give_obj(self, obj):
print("Object released")
self._objects.append(obj)
class Thing(): # This can also be used as a base class
pool = None
def __new__(self, *args):
return self.pool.get_obj()
def __del__(self):
self.pool.give_obj(self)
thing_pool = Pool(Thing)
Thing.pool = thing_pool
Thing()
# Getting object
# Object released
x = Thing()
# Getting object
del x
# Object released