Pro*_*ton 28 python performance memory-management class
我发现类的创建比实例化类慢.
>>> from timeit import Timer as T
>>> def calc(n):
... return T("class Haha(object): pass").timeit(n)
<<After several these 'calc' things, at least one of them have a big number, eg. 100000>>
>>> calc(9000)
15.947055101394653
>>> calc(9000)
17.39099097251892
>>> calc(9000)
18.824054956436157
>>> calc(9000)
20.33335590362549
Run Code Online (Sandbox Code Playgroud)
是的,创建9000个类需要16秒,并且在后续调用中变得更慢.
还有这个:
>>> T("type('Haha', b, d)", "b = (object, ); d = {}").timeit(9000)
Run Code Online (Sandbox Code Playgroud)
给出类似的结果.
但实例化不会受到影响:
>>> T("Haha()", "class Haha(object): pass").timeit(5000000)
0.8786070346832275
Run Code Online (Sandbox Code Playgroud)
在不到一秒的时间内完成5000000个实例.
是什么让这个创作变得昂贵?
为什么创作过程会变慢?
编辑:
如何重现:
开始一个新的python进程,最初的几个"calc(10000)"在我的机器上给出了0.5的数字.并尝试一些更大的值,calc(100000),它甚至不能以10秒结束,中断它,并且计算(10000),给出15秒.
编辑:
其他事实:
如果你在'calc'变慢后gc.collect(),你可以在开始时获得'正常'的速度,但是后续调用的时间会增加
>>> from a import calc
>>> calc(10000)
0.4673938751220703
>>> calc(10000)
0.4300072193145752
>>> calc(10000)
0.4270968437194824
>>> calc(10000)
0.42754602432250977
>>> calc(10000)
0.4344758987426758
>>> calc(100000)
^CTraceback (most recent call last):
File "<stdin>", line 1, in <module>
File "a.py", line 3, in calc
return T("class Haha(object): pass").timeit(n)
File "/usr/lib/python2.7/timeit.py", line 194, in timeit
timing = self.inner(it, self.timer)
File "<timeit-src>", line 6, in inner
KeyboardInterrupt
>>> import gc
>>> gc.collect()
234204
>>> calc(10000)
0.4237039089202881
>>> calc(10000)
1.5998330116271973
>>> calc(10000)
4.136359930038452
>>> calc(10000)
6.625348806381226
Run Code Online (Sandbox Code Playgroud)
Rom*_*huk 32
这可能会给你直觉:
>>> class Haha(object): pass
...
>>> sys.getsizeof(Haha)
904
>>> sys.getsizeof(Haha())
64
Run Code Online (Sandbox Code Playgroud)
类对象是多比类的实例更加复杂和昂贵的结构.
sou*_*eck 10
快速执行以下功能:
def a():
class Haha(object):
pass
def b():
Haha()
Run Code Online (Sandbox Code Playgroud)
得到:
2 0 LOAD_CONST 1 ('Haha')
3 LOAD_GLOBAL 0 (object)
6 BUILD_TUPLE 1
9 LOAD_CONST 2 (<code object Haha at 0x7ff3e468bab0, file "<stdin>", line 2>)
12 MAKE_FUNCTION 0
15 CALL_FUNCTION 0
18 BUILD_CLASS
19 STORE_FAST 0 (Haha)
22 LOAD_CONST 0 (None)
25 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
和
2 0 LOAD_GLOBAL 0 (Haha)
3 CALL_FUNCTION 0
6 POP_TOP
7 LOAD_CONST 0 (None)
10 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
因此.
从它的外观来看,它只是在创建一个类时做了更多的事情.它必须初始化类,将其添加到dicts,以及其他任何地方,而在Haha()只是调用函数的情况下.
正如你所注意到的那样,当速度太慢时再进行垃圾收集,所以Marcin说它可能是内存碎片问题.