admin 管理员组

文章数量: 887021


2024年2月29日发(作者:php正则表一段文字中匹配特定的内容)

201 1年第2O卷第2期 http://www.c-S—a.org.cn 汁算机系统应用 Python语言整数运算实现机制分析与性能评估① 刘巧红,单贵 f上海电子信息职业技术学院计算机应用系一』二海201411) 摘要:Python是最流行的脚本语言之一,但性能较慢。以整数运算为例,通过实验对比评估了Python与C 语言性能差异,从虚拟机源代码层面分析了性能差异产生的原因。在性能优化方面,归纳了几种常用的方法, 并基于其中一种进行了对比测试,取得了较好效果。 关键词:Python:性能分析:性能优化;评估:整数运算 Integer Arithmetic Implementation Mechanism and Performance Evaluations of Python Language LIU Qiao-Hong,SHAN・Gui rDepartment ofComputer,Shanghai Technical Institute ofElectronics&Information,Shanghai 20141 1,China) Abstract:Python is one of the most popular script language,but the performance is a problem.In this paper,we evaluated the performance of integer arithmetic diference between the Python and C languages by experiment,and analyzed the causes of performance diference from the virtual machine source code leve1.The paper summarizes several common methods of Python script performance optimization,by one of these,we achieved good resul ̄on test. Keywords:Python;performance analysis;performance optimization;evaluation;integer arithmetic 1 引言 Python是一种功能强大的动态语言,对于快速应 用开发,是最适合的语言之一。Python语法简单,支 持各种操作系统以及硬件平台,有许多强大的功能特 的本质上性能差异,所以本文选择整数运算为例,对 比评估Python语言与C语言的具体性能差异,并基 于Python虚拟机源代码实现分析了这种差异产生的原 因,以及给出了几种性能优化的途径 。 性。Python还有数量庞大的社区支持,积累了相当丰 富的可复用模块和代码的积累。根据2010年4月的 2 Python与C语言整数运算性能评估 2.1实验环境 操作系统:Ubuntu 9.10 CPU:Intel?Core?2 Duo Processor T7500(4M Cache,2.20 GHz) “TIOBE”程序社区指数,Python排名第7,仅次C, Java,C++,PHP,Basic和c撑,使用量领先于同类型 的TCL、Perl、Ruby。 但Python执行效率问题,一直是应用开发人员考 虑是否应该选用Python的重要顾虑。由于Python是一 C语言编译器:gcc Version 4.4.1 Python虚拟机:Python2.6.5,使用gccVersion4.4.1 build生成。 种动态脚本语言,相对于C、c++等编译型语言,必 定会存在较大的差距,这种性能差异来至于Python虚 拟机实现机制本身。为了消除相关疑惑,需要定量的 2.2运算性能评估算法设计 C语言中,整数可分为8位(char)、l6位(short)、 32位(int),Python中内建整数类型没有区分这么细, 评估明确性能差异的具体幅度,以及差异产生的原因 和机制,最终如何合理优化或规避性能问题1“。 因为相对于网络通信、磁盘文件操作等其他运算, 统一为int对象。为了准确评估3种整数类型在运算 的时候的差异,我们分别进行相应的评估。 整数运算最不受外部因素影响,能够直接提现语言问 ①收稿时问:20IO-05.26;收到修改稿时 :2010—06-2 Experiences Exchange经验交流169 

汁算机系统应用 http://www.c—S-a.org.Clq 20 1 1年第2O卷第2期 程序算法设计t:首先记录执行前的时问,然后调 i:i.1 用整数运算的函数,最后记录执行结束时问并相减得 a=0 到批景运算消耗的时问。 C: void benchmark(void( intTest)O) { Start-time(); intTest0 endYime0; printTimeUsedO; } P),thon" def benchmark(intTest): starttime() intTest() endTimeO printTimeUsed0 批量运算的函数设计的也比较基本,主要是加减 乘除运算。但需要注意的是,C语言与Python语言在 循环控制语句上亦存在差异。为了将这种差异降低到 O.001%,测试函数将最底层的循环展开10W行。通过 Python脚本,可简单的生成这样的测试函数。以int32 的加法测试为例,即: C: void int32Add0 { int a=0: for(i=0;i<l00o000;i++) { a=O: a=a+l; Na=a+l重复l万次 } ) Python: def int32Add0 I:l000000 a=0 、、 hilc(I>O、: 7O经验变流Experiences Exchange a=a+1 //a=a+l重复l万次 2.3评测结果 表1性能评估 2.4结果分析 从计算结果看,在进行整数加法、减法以及除法 运算的时候,Python语言的性能要比C语言的性能慢 约12.5-12.7倍。Python虽然不区分8位、l6位、32 位整数,但处理8位整数的性能要比处理l6位、32 位整数快约6%。Python语言的运行效率相对于C语 言,存在较大的差距。如未采取针对性的优化,Python 语言将较难适用于高并发大计算量的应用场景。 测试结果中C语言表达式a=a*3的执行速度比 a:a+1快30%。 经过分析二进制代码,发现gcc将 a=a*3,转换为a=a+a+a'通过两次在寄存器内的加法 操作完成。而a=a+1,虽然只有一次加法,但操作数l 是从内存寻址的。当代码较长的时,从内存寻址会出 现CPU Cache Missing的情况,因此影响了性能,此处 不展开深入讨论。 整数的加减乘除是最基本的语法,运算性能直接 取决于Python语言本身的内部实现机制。下面我们深 入分忻一下P3 ̄hon虚拟机的内部实现机制及其对性能 的影响。 

2011年第20卷第2期 http:t/www.c-S-a.org.eft 计算机系统应用 3 Python整数运算的内部实现机制分析 3.1 Python虚拟机编译流程 lnitFrame0; InitVariations0; // 始化执行堆栈 //初始化变量 Python语言运行,包括4个步 1: 啦拟叽 始化 for(;;) { //循环解析 节码指令 getNextOpCode0;//取一条 节码指令 getOpArg0; //取指令需要的参数 对脚半进行语法衅折,生成AST结构 编译生成字节代码 解释执行7 代码 图l Python虚拟机运行框架 当我们运行,Python intTest.PY的时候,首先进行 thon虚拟器初始化,完成包括系统参数的初始化、 核心模块的加载、Python语法解析模块的初始化等工 作。完成初始化后,语法解释模块对需执行的脚本文 件(intTest.PY)进行语法解析,生成Python自有的抽象 语法树AST数据结构(Abstract Syntax Tree).然后将 AST编译生成字节代码,即pyc文件中的内容。使用 Python的dis模块,我们可以深入分析所生成的具体 字节码。如a=a+1生成的字节码为: LOAD—NAME 2(a) LOAD—CONST 2(1) BINARYADD STORE——NAME 2(a) 3.2 Python字节码解析执行机制 编译生成的字节码文件,足~个静态文件。它的 执行依赖于Python虚拟机的解析执行环境。Python虚 拟机的解析执行机制是对物理计算机的一种模拟。 Python虚拟机的入口为PyEvaLEvalFrameEx函数,其 作用类似于’CPU’,在该函数中完成对字节码的解释 执行。 将PyEval EvalFrameEx函数的逻辑简化后的伪码 形式表达为: PyEvaIEvalFrameEX0 { evalOp0; //对该指令求值 j } 其中完成的主要工作包括:执行堆栈的初始化;变量 的初始化;逐条取字节码指令执行。 正如物理计算机的指令求值是依赖于当前执行状 态的上下文,譬如函数返回指令具体需要跳转到哪行 代码,Python虚拟机也需要在运行过程中保持上下文 状态。 物理计算机使用系统堆栈来维持上下文,而 Python使用PyFrameObject的链表来模拟CPU运行时 堆栈。在每个PyFrameObject中存放有全局变量表、 局部变量表、内建对象表、下一条字节代码以及动态 对象结构等。 3-3 Python语言的解析执行机制 Python加法语句的解析执行:一次加法(a=a+1), 需要执行4条字节码。 LOAD—NAME 2(a) LOAD—CONST 2(1) BINARYADD ——STORE—NAME 2(a) 其中LOAD NAME是将变量a的值作为加法的 第一变量压到处理栈中,LOAD CONST,是取常数 I作为第二个操作数,BINARY ADD是执行加法运 算,STORE NAME是将结果赋值给变量a。 下面分析一下加法指令BINARY ADD是如何得 以执行的。下面代码参照Python源代码: python/ceva|-c,l 187行一1287行,并进行了简化。 ease BINARYADD: ——W=POP(); //取第一个操作数,一次堆栈读取 v=ToPO; //取第二个操作数,一次堆栈读取 if(w,v均足合法的Pylnt对象){//2次类型检查 a:P3 lnt AS LONG(v); 

计算机系统应用 http://www.C-一S a.-org.cn 2011年第20卷第2期 //取V对象的整数值,PyInt->int b PyInt—AS LONG(w); //取W对象的整数值,Pylnt.>int i (1ong)((unsigned long)a+b); ∥一次整数相加 if(i超出Int范围){ goto slowadd; _x PylntFromLong(i); //用i的值构建一个Pylnt对象,作为结果 } elseif(v,w是字符串){ 执行字符串连接 } else{ slowadd: ——//调用PyNumberAdd计算整数相加 x PyNumberAdd(v,w); } 变量v,W的引用计数减l} 从代码分析一次基本的BINARY ADD执行,涉 及: 2次堆栈取数: w=POP();v=TOP(); 2次类型检查:W,v是否合法的PyInt对象; 2次类型转换:a=Pylnt AS LONG(v);b= Pylnt AS——LONG(w); 一次整数相加:i:(1ong)((unsigned long)a+b); 一次PyIm对象构建:X=Pylnt_FromLong(i); 共8次运算。再加上LOAD NAME, LOAD CONST,STORE NAME指令的开销, Python在执行一次加法(a=a+1)需要进行的运算 次数为:l+1+8+1=l1次。由于虚拟机在字节码循 环执行机制上还有开销,Python执行整数运算的开 销至少是C语言的1l倍以上,与实验结果fl2.5倍) 基本吻合【41。 4 Python性能优化方法与实验 4.1 Python常用性能优化方法 1 72经验交流Experiences Exchange 为了解决Python在实际运行中的性能问题,目前 主要有4种努力方向: 将性能影响最大的部分,通过静态编译型语言实 现,作为扩展库供Python调用。这种方式是最常用也 是最直接的优化方法,能取得接近静态语言的性能。 缺点是,优化与具体应用逻辑相关,所实现的优化不 具备通用性。 提升Python虚拟机的性能。Psyco是这种优化方 案的代表。Psyco是一中可以插入Python解释器的内 部扩展模块,能选择性地用优化的机器代码去替换部 分Python的解释型字节码。当Python解释器运行应 用程序时,Psyco会不时地检查,看是否能用一些专 门的机器代码去替换常规的Python字节码操作。 Psyco的稳定性还需进一步提升。 将Python脚本转化为编译性静态语言代码。PyPy 可以将Python代码翻译成多种底层代码(c、java、.net 等),通过这种方式可以实现运行性能的提升。PyPy 的不足是,尚不能支持100%的Python语法兼容。 通过并行计算方式提升Python执行性能。随着技 术的发展,硬件成本越来越低。通过扩展硬件,来提 升执行性能,可能比优化软件代码更经济。我们可以 使用ParallelPython这个Python模块,实现并行运算【51。 4.2性能优化实验与结果 表2性能测试结果 (下转第244页) 

汁算机系统心用 http:/A ̄ WW.C a.org.cn 2010年第2O卷第2期 到相 的划分里。划分测试/f 仪耍能识别IJj现有的 作,可以大大减少l l门测试的开销。 个划分中的数据,也要能识别山 在划分巾的数据, f3)高度可重复性一个理想的自动测试系统能够 让人随时、方便和迅速的运行大量的测试用例。 他们是用来判断程序能 对无效的输入进行正确处 理【引。 6结束语 5软件测试自动化 用户对软件的需求,随着使用环境的变化,而对 软件产生新的需求。这就要求软件总是在不断变化的。 当开发人员将新的功能模块添加到原米的系统上后, 测试人员不仅要测试新增加的模块,还要重新测试整 随着软件组件的可复用性程度不断提高,越来越 多的软件开发都是对可复用组件进行集成,并配置和 调整已经存在的软件来满足特定的需求。在这种情况 下,软件测试大都是系统测试,单独的组件测试将会 越来越少。所以软件测试将来的工作更多的集中在系 统测试即集成测试和性能测试上面。同时,将自动化 引入软件测试领域能有效地减轻测试人员的劳动强 度,提高测试的效率和质量,从而节省软件开发的成本, 个系统,这无疑增加了软件测试人员的工作量。 自动化测试的目的足弥补手工测试的不足,用自 动的方法来实现和替代人工测试中的~些繁琐和机械 重复的工作,减少测试人员的工作量,保证软件的质 量,提高用户的满意度。 提高软件的质量。软件组件的可复用性程度和软件测 试自动化势必将会对软件测试领域产生重大影响。 软件测试自动化是软件测试领域必须要经历的阶 段,随着应用软件程序规模的不断扩大,复杂程度的 不断提高,用户对软件质量的要求也不断在提高,在 软件的测试活动里适当使用自动化测试是非常必要 的。 参考文献 1赵瑞莲.软件测试方法研究【博士学位论文】.北京:中国中科 院,2001. 2 IAN Sommerville.软件工程.北京:机械工业出版社,2007. 3 ROGERS Pressman.软件工程:实践者的研究方法.北京:机 械工业出版社,2007. 软件测试自动化的好处I : (1)提高测试效率自动化测试可以更有效,可重 复的自动测试。能在更少的时间内完成更多的测试工 作,同时也消耗更少的系统资源。从而能提高测试的 工作效率。 4 RICHARD Bender基于需求的测试是软件测试的本质.程 序员,2010:9. 5许静,陈宏刚,王庆人.软件测试方法简述与展望.计算机工 程与应用.2003:76--77. (2)降低回归测试的开销回归测试中多数的测试 工作是重复的,采用自动化测试来完成这些重复的工 f上接第172页) 采用第一种优化方法,将整数运算的函数转化为 Python的扩展,然后在Python中调用,取得性能测试 结果如表2所示。 6应杭.软件自动化测试技术及应用研究【硕士学位论文】.杭 州:浙江大学,2006. 见的Python性能优化方法,并基于其中一种方法进 行了优化对比测试,证明能够取得较好的性能优化 效果。 从上述结果可看出,将计算量大的运算剥离,改 用C编写成为Python的扩展模块,能够取得丰u当于只 比C语言代码的性能慢10%的性能,较大程度改善了 性能问题。 参考文献 】Python官方网站.[2010—5.13].http:llpython.org/about/ index.html 2罗霄,任勇,山秀明.基于Python的混合语言编程及其实现. 计算机应用与软件,2004,21(12):17一l8. 3陈儒.Python源代码剖析.北京:电子工业出版社,2008.1— 480. 5结束语 Python是最流行的脚本浯苦之一一,但性能较慢。 本文以秘数运算为例,通过实验对比评fl}i了P3lhon与 C语苦性能荠骨,并从虚拟机内部源代码的层面分 析了性能差异产生的原阕。本文还总结归纳几种常 244专鲶・综述Special Issue 4 恩,宋古广译.Python核心编程.北京:人民邮电出版社 2008.1—654. 5赖勇浩.Python性优化经验谈.程序员,2008,4:99—103. 


本文标签: 性能 测试 运算 执行 优化