python lua 性能比较 内存_Lua 的速度为什么比 Python 快?

最近研究了下Python的代码,有了一些新的发现。大量的内置字符串常量没有做Intern优化,在python源码中搜索形如"__dict__"之类的常量是这么用的:

PyObject* xxxObject = PyObject_GetAttrString(someObject, "__dict__");

这样会导致每次调用到这里时都会去查找一下有没有创建过这个字符串。实际上对于脚本虚拟机中这类常量应该提前分配好,直接使用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的实现。

5. 对轻类型的支持不好,为了OOP实现得太重了。这一点其他答案说得比较多,这部分主要是内存消耗和是否走GC的差异,在这方面lua的内置类型number/lightuserdata不走gc的优势很明显。

6. 虚拟机实现上的差异,lua register-based VM可以让指令的数量少很多。Python这方面天然比较吃亏且没有什么简单的解决办法。

7. C-API效率上python的api比较难用,而使用封装好的绑定库会进一步增加API调用上的开销。一个简单地读取自定义C对象中某个属性的操作,从发起调用到读到对应属性的半程操作中(不算写回到脚本),Python有80%的时间花费在调用链和数据转换上,相比Lua只有50%左右。

后面的想到再说~

总的来说,如果把脚本语言比作一个垃圾处理站,那么Python就是不管你要扔什么垃圾,统一都通过一个入口倒进去,然后垃圾处理站内部再用复杂的流程去分类处理。而Lua会预设几个大的门类,常用的纸箱饮料瓶专窗背后直接对接再生制品的工厂,厨余垃圾专窗背后直接对接饲料场,剩下的再走复杂流程。

大多数情况下,来倒垃圾的都在lua预设的那几个大门类里。

最后贴一下Python和Lua在如下几个方面实测的效率差异吧,平台Windows 64Bit:基础数值计算:Lua速度是Python的10-15倍

与宿主语言交互:Lua速度是Python的3-5倍

字符串操作:两者差不多

综合性能:具体取决于代码中各种操作的比例,实际效果Lua一般在Python的2-4倍之间。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python中,可以使用unluac模块来反编译luac_Lua程序。具体步骤如下: 1. 安装unluac模块。可以使用pip命令进行安装,命令如下: ``` pip install unluac ``` 2. 编写Python脚本来调用unluac模块进行反编译。以下是一个简单的示例脚本: ``` import unluac with open('test.luac', 'rb') as f: data = f.read() decompiled = unluac.decompile(data) with open('test.lua', 'w') as f: f.write(decompiled) ``` 该脚本将test.luac文件反编译为test.lua文件。 3. 将反编译后的Lua代码导入到IDA Pro中。可以使用IDA Pro的Lua插件进行处理。 1. 在IDA Pro中,选择File -> Script file,打开Lua脚本窗口。 2. 在窗口中输入以下代码: ``` local f = io.open("test.lua", "r") local content = f:read("*all") f:close() LoadSource(content, "test.lua") ``` 3. 点击Run按钮,将Lua代码加载到IDA Pro中。 4. 编写IDA Pro处理器模块。可以使用IDA Pro的Python API编写处理器模块,对Lua代码进行分析和处理。以下是一个示例模块: ``` import idaapi class LuaProcessor(idaapi.processor_t): id = 0x8000 + 1 flag = idaapi.PR_USE32 | idaapi.PR_DEFSEG32 cnbits = 8 dnbits = 8 psnames = ["luac"] plnames = ["Luac bytecode"] segreg_size = 0 instruc_start = 0 assembler = { "flag" : flag, "uflag" : 0, "name" : "Luac assembler", "origin" : "luac", "notify" : None, "header" : None, "footer" : None, "segstart" : None, "segend" : None, "assume" : None, "flag2" : 0, "cmnt" : ";", "ascsep" : '"', "accsep" : "'", "esccodes" : "\"'", "a_ascii" : "db", "a_byte" : "db", "a_word" : "dw", "a_dword" : "dd", "a_qword" : "dq", "a_oword" : "xmmword", "a_float" : "dd", "a_double" : "dq", "a_tbyte" : "dt", "a_packreal" : "dq", "a_dups" : "#dups", "a_bss" : "res", "a_seg" : "seg", "a_curip" : "$", "a_public" : "public", "a_weak" : "weak", "a_extrn" : "extrn", "a_comdef" : "comm", "a_align" : "align", "lbrace" : "(", "rbrace" : ")", "a_mod" : "%", "a_band" : "&", "a_bor" : "|", "a_xor" : "^", "a_bnot" : "~", "a_shl" : "<<", "a_shr" : ">>", "a_sizeof_fmt" : "size %s", } def PROCESSOR_ENTRY(): return LuaProcessor() ``` 该模块将Lua代码识别为Luac bytecode,并使用Luac assembler进行处理。 以上就是使用Python反编译luac_Lua程序并为其编写IDA Pro处理器模块的一般步骤。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值