orangle / blog

博客--自我学习监督
http://orangleliu.info
3 stars 0 forks source link

Python 性能小测试等 #11

Open orangle opened 7 years ago

orangle commented 7 years ago

动态加载对象

exec 和 evel比较

In [9]: %timeit t=eval('TTest'); t()
100000 loops, best of 3: 4.94 µs per loop

In [10]: %timeit exec("TTest()")
100000 loops, best of 3: 6.19 µs per loop

exec动态执行和编译成bytecode执行对比

liuzhizhi@lzz-rmbp|hexo_blog # python -mtimeit -s 'code = "a = 2; b = 3; c = a * b"' 'exec code'
100000 loops, best of 3: 13 usec per loop
liuzhizhi@lzz-rmbp|hexo_blog # python -mtimeit -s 'code = compile("a = 2; b = 3; c = a * b","<string>", "exec")' 'exec code'
1000000 loops, best of 3: 0.562 usec per loop

阅读: http://lucumr.pocoo.org/2011/2/1/exec-in-python/

需要记住的一点就是从 源码转化成为bytecode是一个非常消耗资源的过程,程序执行中总是去做这种转化,效率就会很低了。全局变量是存储在字典中,本地变量也有一个字典,但是还有个fast locals来存储资源(数组类型),优先使用它,所以更快。

动态获取属性

Why is getattr() so much slower than self.dict.get()? 或者这个 http://stackoverflow.com/questions/14084897/getattr-versus-dict-lookup-which-is-faster 这种一般用在动态调用类的方法,可配置调用里面,也是经常用的模式。

慢的原因: getattr() 是python的一个标准接口,它需要兼容的东西非常多,做了很多工作性能当人会差一些。 而 dict 则要简单直接的多,所以速度也快一些. getattr(Obj, 'xxx') 的作用等于 ‘Obj.xxx’, 会慢一些。

>>> import timeit
>>> class Foo(object):
...     pass
...
>>> f = Foo()
>>> f.bar = "lzz"
>>> timeit.timeit("getattr(f, 'bar')", 'from __main__ import f')
0.13153386116027832
>>> timeit.timeit("f.__dict__['bar']", 'from __main__ import f')
0.10464715957641602