python:一个有许多方法的类初始化会花费更长的时间吗?
我有一个程序,它必须从一个有12-14个方法的类中连续创建数千个对象。它们属于复杂类这一事实是否会导致在创建更简单的对象(如列表或字典)或其他方法更少的对象时性能下降 关于我的情况的一些细节: 我有一堆“文本”对象,它们不断地创建和刷新内容的“打印”。打印对象有许多方法,但只有少数属性。打印对象不能包含在文本对象中,因为文本对象需要“可重用”并制作其打印的多个独立副本,这样就排除了刷新时仅交换打印对象属性的可能性 我过得好吗python:一个有许多方法的类初始化会花费更长的时间吗?,python,objectinstantiation,Python,Objectinstantiation,我有一个程序,它必须从一个有12-14个方法的类中连续创建数千个对象。它们属于复杂类这一事实是否会导致在创建更简单的对象(如列表或字典)或其他方法更少的对象时性能下降 关于我的情况的一些细节: 我有一堆“文本”对象,它们不断地创建和刷新内容的“打印”。打印对象有许多方法,但只有少数属性。打印对象不能包含在文本对象中,因为文本对象需要“可重用”并制作其打印的多个独立副本,这样就排除了刷新时仅交换打印对象属性的可能性 我过得好吗 在应用程序刷新时,是否连续创建新的打印对象及其所有方法 分解类并将打
- 在应用程序刷新时,是否连续创建新的打印对象及其所有方法
- 分解类并将打印对象转换为简单结构,将方法转换为以对象为参数的独立函数
我认为,这取决于使用包含在其中的所有方法生成新对象是否会产生巨大的成本,而不是必须将所有独立函数导入到将被称为对象方法的任何地方。不管类有多复杂;创建实例时,只存储对实例所在类的引用。所有方法都可以通过这个引用访问。不,它不应该有什么区别 当您执行以下操作时,请考虑:
a = Foo()
a.bar()
对bar
方法的调用实际上被翻译为:
Foo.bar(a)
也就是说,bar
在类定义下是“静态”的,并且该函数只存在一个实例。当你这样看它时,它表明不,方法的数量不会产生重大影响。这些方法是在您第一次运行Python程序而不是创建对象时实例化的。我做了一些测试
我有以下功能:
def call_1000000_times(f):
start = time.time()
for i in xrange(1000000):
f(a=i, b=10000-i)
return time.time() - start
如您所见,此函数接受另一个函数,调用它1000000次,并返回所用的时间(以秒为单位)
我还创建了两个类:
小班:
class X(object):
def __init__(self, a, b):
self.a = a
self.b = b
还有一个相当大的:
class Y(object):
def __init__(self, a, b):
self.a = a
self.b = b
def foo(self): pass
def bar(self): pass
def baz(self): pass
def anothermethod(self):
pass
@classmethod
def hey_a_class_method(cls, argument):
pass
def thisclassdoeswaytoomuch(self): pass
def thisclassisbecomingbloated(self): pass
def almostattheendoftheclass(self): pass
def imgonnahaveacouplemore(self): pass
def somanymethodssssss(self): pass
def should_i_add_more(self): pass
def yes_just_a_couple(self): pass
def just_for_lolz(self): pass
def coming_up_with_good_method_names_is_hard(self): pass
结果是:
>>> call_1000000_times(dict)
0.2680389881134033
>>> call_1000000_times(X)
0.6771988868713379
>>> call_1000000_times(Y)
0.6260080337524414
正如您所看到的,大型类和小型类之间的差异非常小,在这种情况下大型类甚至更快。我假设如果你用同一个类型多次运行这个函数,并平均这些数字,它们会更接近,但现在是凌晨3点,我需要睡眠,所以我现在不准备设置它
另一方面,仅仅调用dict
大约快2.5倍,因此如果瓶颈是实例化,那么这里可能是优化的地方
但是要警惕过早的优化。类,通过将数据和代码放在一起,可以使您的代码更容易理解和构建(函数式编程爱好者,这里不适合作参数)。最好使用python或其他性能度量工具来找出代码中哪些部分使其速度变慢。类包含数据和方法,初始化通常意味着分配数据,方法只存在一个副本,无论创建多少对象,如果你担心启动延迟,使用一种编译语言,如C++或C语言,这是一种更好的面向对象语言,而且更容易学习。闭包有带有私有数据的方法,因此,虽然闭包在代码上很紧凑,但如果它很复杂,它在内存中可能会很大。子类化
dict
是否是更好的选择?请对其进行分析。我在床上。@kelvinsong:不太重要。类实例(不包括带有\uu插槽的类的特殊情况)在任何情况下都是按照dict
实现的,命名为\uu dict
(尽管在现代Python 3中,它是一种优化的密钥共享dict
,如果在\uuuu init\uuuu
中初始化同一组属性名,并且在\uuuu init\uuuu
之后不添加或删除名称,则比普通的dict
使用更少的内存。),因此无论发生什么情况,都会进行dict
查找。仅当您希望使用foo['name']
语法而不是foo.name
进行访问时,才扩展dict
。