最近研究了下Python的代码,有了一些新的发现。
1、大量的内置字符串常量没有做Intern优化,在python源码中搜索形如"__dict__"之类的常量是这么用的:class="highlight">
这样会导致每次调用到这里时都会去查找一下有没有创建过这个字符串。实际上对于脚本虚拟机中这类常量应该提前分配好,直接使用PyObject引用,而不是每次都尝试去创建一个。要命的是GetAttrString在很多基础操作中会大量使用…… lua对这些字串则都缓存了起来。
在Python 3之后,python使用了_Py_Identifier缓存了一些静态名字,使得这部分性能得到了一定的优化。
2、使用RC和TRACE的GC方案导致需要大量,频繁地增减计数器。lua没有这个开销。
3、Python 中调用函数会把参数打包成一个tuple,频繁创建和删除tuple造成比较大的开销(虽然内部对tuple有缓存机制,但是仍然会增加约10%的消耗)。Python 2中instancemethod会导致重新打包一次tuple再去call,加重了这个问题。实际上由于Python不支持多线程,在有些情况下可以使用复用这些tuples的,没必要每次都重新创建。lua则直接在lua_State的栈上展开了参数,不需要打包数组。
4、运算符的调用链和需要处理的动态情况过多,导致自定义一个支持运算符的类型的性能极差。相比lua的metatable少量的table查找,python的实现极其复杂。有兴趣地童鞋可以看看PyNumber_Add