为什么在Python中创建类比实例化类要慢得多? - python

我发现创建类比实例化类要慢得多。

>>> 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

是的,创建9000个类花费了16秒,并且在随后的调用中变得更加慢。

还有这个:

>>> T("type('Haha', b, d)", "b = (object, ); d = {}").timeit(9000)

给出相似的结果。

但是实例化不会受到影响:

>>> T("Haha()", "class Haha(object): pass").timeit(5000000)
0.8786070346832275

不到一秒的时间达到5000000个实例。

是什么使创作如此昂贵?

为什么创建过程会变慢?

编辑:

繁殖方法:

开始一个新的python进程,最初的几个“calc(10000)”在我的机器上给出0.5的数字。尝试更大的值calc(100000),它甚至不能在10秒内结束,将其中断,而calc(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

参考方案

啊哈哈哈!知道了!

这种性能是在没有this patch的Python版本上完成的吗? (提示:它是)

如果需要证明,请检查行号。

Marcin是正确的:当结果看起来很棘手时,您可能已经有了一个棘手的基准。运行gc.disable(),结果将重现。它只是表明,当您禁用垃圾收集时,您会得到垃圾结果!

更明确地说,运行长期基准测试会破坏事情的原因是:

  • timeit禁用垃圾收集,因此过大的基准会花费更多(指数)的
  • timeit未还原异常
  • 上的垃圾回收

  • 您使用异步异常退出了长时间运行的进程,关闭了垃圾回收
  • Python 3运算符>>打印到文件 - python

    我有以下Python代码编写项目的依赖文件。它可以在Python 2.x上正常工作,但是在使用Python 3进行测试时会报告错误。depend = None if not nmake: depend = open(".depend", "a") dependmak = open(".depend.mak&#…

    Python:检查是否存在维基百科文章 - python

    我试图弄清楚如何检查Wikipedia文章是否存在。例如,https://en.wikipedia.org/wiki/Food 存在,但是https://en.wikipedia.org/wiki/Fod 不会,页面只是说:“维基百科没有此名称的文章。”谢谢! 参考方案 >>> import urllib >>> prin…

    Python:对于长时间运行的进程,通过还是休眠? - python

    我正在编写一个队列处理应用程序,该应用程序使用线程等待和响应要发送到该应用程序的队列消息。对于应用程序的主要部分,只需要保持活动状态即可。对于像这样的代码示例:而True: 通过要么而True: time.sleep(1)哪一个对系统的影响最小?除了保持python应用运行外,什么都不做的首选方式是什么? 参考方案 我可以想象time.sleep()会减少系…

    Python:无符号32位按位算术 - python

    试图回答另一篇有关其解决方案涉及IP地址和网络掩码的文章时,我陷入了普通的按位算法。在Python中,是否存在一种标准的方式来进行按位AND,OR,XOR,NOT运算,假设输入是“32位”(可能是负数)整数或long,并且结果必须是[[ 0,2 ** 32]?换句话说,我需要一个与无符号长整数之间的C按位运算有效的Python对应物。编辑:具体问题是这样的:…

    Python Pandas导出数据 - python

    我正在使用python pandas处理一些数据。我已使用以下代码将数据导出到excel文件。writer = pd.ExcelWriter('Data.xlsx'); wrong_data.to_excel(writer,"Names which are wrong", index = False); writer.…