python:具有许多方法的 class 会花费更长的时间来初始化吗?
python: will an class with many methods take longer to initialize?
我有一个程序必须从 class 中连续创建数千个对象,该对象具有大约 12–14 个方法。它们是复杂的 class 的事实是否会导致性能比创建更简单的对象(如列表或字典),甚至创建另一个方法更少的对象更重要?
关于我的情况的一些细节:
我有一堆“文本”对象,它们不断创建和刷新其内容的“印刷品”。打印对象有很多方法,但只有少数属性。打印对象不能包含在文本对象中,因为文本对象需要“可重用”并制作其打印的多个独立副本,因此排除了在刷新时仅交换打印对象的属性。
我过得更好吗,
- 是否在应用程序刷新时使用其所有方法不断创建新的打印对象?
- 分解 class 并将打印对象转换为简单的结构,将方法转换为以对象为参数的独立函数?
我假设这取决于生成包含所有方法的新对象与必须将所有独立函数导入到它们将被称为对象方法的任何地方是否会产生大量成本.
class 有多复杂并不重要;当您创建一个实例时,您只存储对实例的 class 的引用。所有方法都通过这个引用访问。
不,应该没什么区别。
考虑一下当您执行以下操作时:
a = Foo()
a.bar()
对 bar
方法的调用实际上在幕后转换为:
Foo.bar(a)
即bar
是 class 定义下的 "static",并且该函数只有一个实例。当您以这种方式看待它时,它表明不,方法的数量不会产生重大影响。当您首先 运行 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 次,以及 returns 花费的时间,以秒为单位。
我还创建了两个 classes:
小class:
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
如您所见,大 class 和小 class 之间的差异非常小,在这种情况下大 class 甚至更快。我假设如果你 运行 这个函数多次使用相同的类型,并对数字进行平均,它们会更接近,但现在是凌晨 3 点,我需要睡觉,所以我不会正确设置它现在。
另一方面,仅调用 dict
大约快 2.5 倍,因此如果您的瓶颈是实例化,这可能是优化的地方。
不过要提防过早的优化。 类,通过将数据和代码放在一起,可以使您的代码更易于理解和构建(函数式编程爱好者,这不是争论的地方)。使用 python profiler 或其他性能测量工具找出代码的哪些部分正在减慢速度可能是个好主意。
我有一个程序必须从 class 中连续创建数千个对象,该对象具有大约 12–14 个方法。它们是复杂的 class 的事实是否会导致性能比创建更简单的对象(如列表或字典),甚至创建另一个方法更少的对象更重要?
关于我的情况的一些细节: 我有一堆“文本”对象,它们不断创建和刷新其内容的“印刷品”。打印对象有很多方法,但只有少数属性。打印对象不能包含在文本对象中,因为文本对象需要“可重用”并制作其打印的多个独立副本,因此排除了在刷新时仅交换打印对象的属性。
我过得更好吗,
- 是否在应用程序刷新时使用其所有方法不断创建新的打印对象?
- 分解 class 并将打印对象转换为简单的结构,将方法转换为以对象为参数的独立函数?
我假设这取决于生成包含所有方法的新对象与必须将所有独立函数导入到它们将被称为对象方法的任何地方是否会产生大量成本.
class 有多复杂并不重要;当您创建一个实例时,您只存储对实例的 class 的引用。所有方法都通过这个引用访问。
不,应该没什么区别。
考虑一下当您执行以下操作时:
a = Foo()
a.bar()
对 bar
方法的调用实际上在幕后转换为:
Foo.bar(a)
即bar
是 class 定义下的 "static",并且该函数只有一个实例。当您以这种方式看待它时,它表明不,方法的数量不会产生重大影响。当您首先 运行 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 次,以及 returns 花费的时间,以秒为单位。
我还创建了两个 classes:
小class:
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
如您所见,大 class 和小 class 之间的差异非常小,在这种情况下大 class 甚至更快。我假设如果你 运行 这个函数多次使用相同的类型,并对数字进行平均,它们会更接近,但现在是凌晨 3 点,我需要睡觉,所以我不会正确设置它现在。
另一方面,仅调用 dict
大约快 2.5 倍,因此如果您的瓶颈是实例化,这可能是优化的地方。
不过要提防过早的优化。 类,通过将数据和代码放在一起,可以使您的代码更易于理解和构建(函数式编程爱好者,这不是争论的地方)。使用 python profiler 或其他性能测量工具找出代码的哪些部分正在减慢速度可能是个好主意。