重现unladen-swallow的性能对比实验
来源:互联网 发布:淘宝男装外贸 编辑:程序博客网 时间:2024/05/16 07:14
unladen-swallow项目的失败实际上宣告了大幅度改变动态语言的性能是不可能的,个人觉得像python这样的动态语言改变他的性能的意义也不是特别大.没一种语言都有他实际的应用领域,其次随着计算机性能的越来越好,运行效率的问题不会显得太突出
我在编译unladen-swallow这个项目的时候,遇到一个很诡异的make错误:
-g -O3 -I. -IInclude -I../src -I../src/Include -DPy_BUILD_CORE -o Python/bltinmodule.o ../src/Python/bltinmodule.c #(这一行是ok的)
下一行的提示
../src/Python/makeopcodetargets.py ../src/Python/opcode_targets.h
:没有那个文件或目录#(no such file or directory)
make: *** [../src/Python/opcode_targets.h] 错误 127
我的第一反应是../src/Python/makeopcodetargets.py ../src/Python/opcode_targets.h 这两个东西是不是不存在,于是我去文件夹里面寻找了一下,发现这两个文件都存在的,于是我就想,是不是makeopcodetargets.py这个python脚本在运行的时候遇到以它所在的目录为当前目录,然后在当前目录下寻找../scr/Python/opcode_targets.h.于是我做了一下测试,发现脚本在运行的时候当前目录并没有改变.接下来我能想的就是看看makeopcodetargets.py这个文件里面倒是是什么,在下面我列了出来
#! /usr/bin/env python"""Generate C code for the jump table of the threaded code interpreter(for compilers supporting computed gotos or "labels-as-values", such as gcc)."""import impimport osdef find_module(modname): """Finds and returns a module in the local dist/checkout. """ modpath = os.path.join( os.path.dirname(os.path.dirname(__file__)), "Lib") return imp.load_module(modname, *imp.find_module(modname, [modpath]))def write_contents(f): """Write C code contents to the target file object. """ opcode = find_module("opcode") targets = ['_unknown_opcode'] * 256 for opname, op in opcode.opmap.items(): if opname == "STOP_CODE": # XXX opcode not implemented continue targets[op] = "TARGET_%s" % opname f.write("static void *opcode_targets[256] = {\n") f.write(",\n".join("\t&&%s" % s for s in targets)) f.write("\n};\n")if __name__ == "__main__": import sys assert len(sys.argv) < 3, "Too many arguments" if len(sys.argv) == 2: target = sys.argv[1] else: target = "Python/opcode_targets.h" f = open(target, "w") try: write_contents(f) finally: f.close()
这个.py中的代码有两个函数,find_module和write_contents.既然代码比较短,我就直接把这段代码的意思给看了.当然先从注释看起,可以看出这主要是生成一个c代码,为生成线程代码解释器的跳转表服务.看完之后发现问题也不在这儿.
既然都不是这写原因,那我只能去看make文件了,找到了对应的make文件的657行
$(OPCODETARGETS_H): $(OPCODETARGETGEN_FILES) $(OPCODETARGETGEN) $(OPCODETARGETS_H)Python/eval.o: Python/eval.cc $(OPCODETARGETS_H)
奇葩了,完全没有问题,这是不是系统的原因,我用的是国产的linux deepin,于是我去实验室在ubuntu上重新实现了一下上面的过程,这个时候出现了新的问题。也就是/usr/include/gnu/stubs-32.h,no such file or directory。我对linux的内核不是特别了解,没法从根源去寻找原因,这个时候我就上网寻找答案,将网上可以有的答案都实现了一遍,发现还是没有解决问题。然后我去/usr/gnu文件夹下去寻找,发现确实没有stubs-32.h文件,但是有stubs.h和stubs-64.h。难道是因为我装的ubuntu 12.04 LTS导致stubs-32.h被装到别的地方去了?search文件,发现这个东西跑到/usr/include/i386-linux-gnu/gnu/里面去了。将其copy到/usr/include/gnu/里面,接着make。没有出现上面的奇葩问题,顺利通过编译。unladen-swallow 成功生成,看到python可执行文件略感欣慰,擦,废了哥一天时间
最后我将得到的优化后的python在benchmark上运行了一下,主要跑了一个django的程序,迭代100次。得到了unladen-swallow在llvm开启优化功能后的性能和未开启优化功能的运行效率对比,
Unladen-Swallow是隶属于Google的开源项目,初始目标:1)将Python的速度提高至少5倍;2)用它写出来的Python应用程序性能必须能十分稳定;3)提供与CPython源代码级的兼容;4)提供与CPython源代码级的扩展模块的兼容;5)这个项目会逐渐成为Python实现的一个独立的分支。这个项目将Python字节码架构在LLVM上面,利用LLVM的JIT编译器实现部分优化,保留Python其他部分不变,他这么做的原因是Python的大部分的运行时间用在eval循环里面。在Q1版本中,用vmgen[2]重新实现了eval核心循环,提高了垃圾回收和cPickle的性能,简化帧对象,提高全局和内建对象的查询速度;在Q2版本中加入了基于LLVM的JIT编译器;在Q3版本中将执行性能提高了15-70%。最后做了一个对比,将Q1和Q2以及Q3的性能分别做了一个测试并将我的方法用在Q1,Q2,Q3,Q4上面,得到了性能的提升。Q4和CPython的性能对比如上图所示。
从这两幅图片可以看出来,效率还是有一定的提高的,只是对于一个本来效率就不太高的语言来说,这样的提高有多大意义就另当别论了,但有一点是肯定的,这跟unladen-swallow开始的目标差的太远了……
- 重现unladen-swallow的性能对比实验
- Unladen Swallow项目计划
- Unladen Swallow 2009Q2
- Unladen Swallow 的失败与教训以及PyPy
- PostgreSQL和MySQL的性能对比实验
- swallow
- 数据库性能对比测试实验
- 性能测试重现Session引发的OOM
- 性能测试重现Session引发的OOM
- Java单例模式在多线程环境下的性能测试对比实验分析
- 几种字符串匹配算法性能简单实验对比
- 判断字符串为空方法性能对比实验
- 阻塞队列的性能对比
- 对比主流Bootloader的性能
- 阻塞队列的性能对比
- 阻塞队列的性能对比
- 反射调用的性能对比
- 如何重现难以重现的bug
- SecureCRT的详细使用教程 二
- shared_from_this多继承时遇到的问题
- operator new和new operator
- 分享自己写的一个小工具RGB转十六进制(高手勿喷)
- 初识JPA外键关联:指向外部表的主键
- 重现unladen-swallow的性能对比实验
- 你有多强大?
- hdu-4466-Triangle 数学题
- 编程工具的回忆
- Android:定制化CursorAdapter,简洁版
- sublime text2 插件 - ctags的使用
- 10719 - Quotient Polynomial
- DM8148 nand 启动文件
- 工作第一天