源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

深入理解Python 代码优化详解

  • 时间:2021-05-29 13:48 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:深入理解Python 代码优化详解
 选择了脚本语言就要忍受其速度,这句话在某种程度上说明了 python 作为脚本的一个不足之处,那就是执行效率和性能不够理想,特别是在 performance 较差的机器上,因此有必要进行一定的代码优化来提高程序的执行效率。如何进行 Python 性能优化,是本文探讨的主要问题。本文会涉及常见的代码优化方法,性能优化工具的使用以及如何诊断代码的性能瓶颈等内容,希望可以给 Python 开发人员一定的参考。 [img]http://files.jb51.net/file_images/article/201410/201410270854111.jpg[/img]   代码优化能够让程序运行更快,它是在不改变程序运行结果的情况下使得程序的运行效率更高,根据 80/20 原则,实现程序的重构、优化、扩展以及文档相关的事情通常需要消耗 80% 的工作量。优化通常包含两方面的内容:减小代码的体积,提高代码的运行效率。   改进算法,选择合适的数据结构     一个良好的算法能够对性能起到关键作用,因此性能改进的首要点是对算法的改进。在算法的时间复杂度排序上依次是:     O(1) -> O(lg n) -> O(n lg n) -> O(n^2) -> O(n^3) -> O(n^k) -> O(k^n) -> O(n!)     因此如果能够在时间复杂度上对算法进行一定的改进,对性能的提高不言而喻。但对具体算法的改进不属于本文讨论的范围,读者可以自行参考这方面资料。下面的内容将集中讨论数据结构的选择。  •字典 (dictionary) 与列表 (list)     Python 字典中使用了 hash table,因此查找操作的复杂度为 O(1),而 list 实际是个数组,在 list 中,查找需要遍历整个 list,其复杂度为 O(n),因此对成员的查找访问等操作字典要比 list 更快。     清单 1. 代码 dict.py
[url=http://psyco.sourceforge.net/]http://psyco.sourceforge.net/[/url]     Pypy     PyPy 表示 “用 Python 实现的 Python”,但实际上它是使用一个称为 RPython 的 Python 子集实现的,能够将 Python 代码转成 C, .NET, Java 等语言和平台的代码。PyPy 集成了一种即时 (JIT) 编译器。和许多编译器,解释器不同,它不关心 Python 代码的词法分析和语法树。 因为它是用 Python 语言写的,所以它直接利用 Python 语言的 Code Object.。 Code Object 是 Python 字节码的表示,也就是说, PyPy 直接分析 Python 代码所对应的字节码 ,,这些字节码即不是以字符形式也不是以某种二进制格式保存在文件中, 而在 Python 运行环境中。目前版本是 1.8. 支持不同的平台安装,windows 上安装 Pypy 需要先下载 [url=https://bitbucket.org/pypy/pypy/downloads/pypy-1.8-win32.zip]https://bitbucket.org/pypy/pypy/downloads/pypy-1.8-win32.zip[/url],然后解压到相关的目录,并将解压后的路径添加到环境变量 path 中即可。在命令行运行 pypy,如果出现如下错误:”没有找到 MSVCR100.dll, 因此这个应用程序未能启动,重新安装应用程序可能会修复此问题”,则还需要在微软的官网上下载 VS 2010 runtime libraries 解决该问题。具体地址为[url=http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=5555]http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=5555[/url]     安装成功后在命令行里运行 pypy,输出结果如下:
[url=http://cython.org/release/Cython-0.15.1.zip]http://cython.org/release/Cython-0.15.1.zip[/url]  --2012-04-16 22:08:35--  [url=http://cython.org/release/Cython-0.15.1.zip]http://cython.org/release/Cython-0.15.1.zip[/url]  Resolving cython.org... 128.208.160.197  Connecting to cython.org|128.208.160.197|:80... connected.  HTTP request sent, awaiting response... 200 OK  Length: 2200299 (2.1M) [application/zip]  Saving to: `Cython-0.15.1.zip'  100%[======================================>] 2,200,299   1.96M/s   in 1.1s  2012-04-16 22:08:37 (1.96 MB/s) - `Cython-0.15.1.zip' saved [2200299/2200299]
  第二步:解压
[url=http://cython.org]http://cython.org[/url]) is a compiler for code written in the  Cython language.  Cython is based on Pyrex by Greg Ewing.  Usage: cython [options] sourcefile.{pyx,py} ...  Options:   -V, --version                  Display version number of cython compiler   -l, --create-listing           Write error messages to a listing file   -I, --include-dir <directory>  Search for include files in named directory                                  (multiple include directories are allowed).   -o, --output-file <filename>   Specify name of generated C file   -t, --timestamps               Only compile newer source files   -f, --force                    Compile all source files (overrides implied -t)   -q, --quiet                    Don't print module names in recursive mode   -v, --verbose                  Be verbose, print file names on multiple compil ation   -p, --embed-positions          If specified, the positions in Cython files of each   function definition is embedded in its docstring.   --cleanup <level>   Release interned objects on python exit, for memory debugging.     Level indicates aggressiveness, default 0 releases nothing.   -w, --working <directory>   Sets the working directory for Cython (the directory modules are searched from)   --gdb Output debug information for cygdb   -D, --no-docstrings               Strip docstrings from the compiled module.   -a, --annotate               Produce a colorized HTML version of the source.   --line-directives               Produce #line directives pointing to the .pyx source   --cplus               Output a C++ rather than C file.   --embed[=<method_name>]               Generate a main() function that embeds the Python interpreter.   -2          Compile based on Python-2 syntax and code seman tics.   -3          Compile based on Python-3 syntax and code seman tics.   --fast-fail     Abort the compilation on the first error   --warning-error, -Werror       Make all warnings into errors   --warning-extra, -Wextra       Enable extra warnings   -X, --directive <name>=<value>   [,<name=value,...] Overrides a compiler directive
  其他平台上的安装可以参考文档:[url=http://docs.cython.org/src/quickstart/install.html]http://docs.cython.org/src/quickstart/install.html[/url]     Cython 代码与 python 不同,必须先编译,编译一般需要经过两个阶段,将 pyx 文件编译为 .c 文件,再将 .c 文件编译为 .so 文件。编译有多种方法:  •通过命令行编译:假设有如下测试代码,使用命令行编译为 .c 文件。
[u]复制代码[/u] 代码如下:
def sum(int a,int b):         print a+b  [root@v5254085f259 test]# cython sum.pyx  [root@v5254085f259 test]# ls  total 76  4 drwxr-xr-x 2 root root  4096 Apr 17 02:45 .  4 drwxr-xr-x 4 root root  4096 Apr 16 22:20 ..  4 -rw-r--r-- 1 root root    35 Apr 17 02:45 1  60 -rw-r--r-- 1 root root 55169 Apr 17 02:45 sum.c  4 -rw-r--r-- 1 root root    35 Apr 17 02:45 sum.pyx
  在 linux 上利用 gcc 编译为 .so 文件:
[u]复制代码[/u] 代码如下:
[root@v5254085f259 test]# gcc -shared -pthread -fPIC -fwrapv -O2  -Wall -fno-strict-aliasing -I/usr/include/python2.4 -o sum.so sum.c  [root@v5254085f259 test]# ls  total 96  4 drwxr-xr-x 2 root root  4096 Apr 17 02:47 .  4 drwxr-xr-x 4 root root  4096 Apr 16 22:20 ..  4 -rw-r--r-- 1 root root    35 Apr 17 02:45 1  60 -rw-r--r-- 1 root root 55169 Apr 17 02:45 sum.c  4 -rw-r--r-- 1 root root    35 Apr 17 02:45 sum.pyx  20 -rwxr-xr-x 1 root root 20307 Apr 17 02:47 sum.so
  使用 distutils 编译     建立一个 setup.py 的脚本:
[u]复制代码[/u] 代码如下:
from distutils.core import setup  from distutils.extension import Extension  from Cython.Distutils import build_ext  ext_modules = [Extension("sum", ["sum.pyx"])]  setup(     name = 'sum app',     cmdclass = {'build_ext': build_ext},     ext_modules = ext_modules  )  [root@v5254085f259 test]#  python setup.py build_ext --inplace  running build_ext  cythoning sum.pyx to sum.c  building 'sum' extension  gcc -pthread -fno-strict-aliasing -fPIC -g -O2 -DNDEBUG -g -fwrapv -O3  -Wall -Wstrict-prototypes -fPIC -I/opt/ActivePython-2.7/include/python2.7   -c sum.c -o build/temp.linux-x86_64-2.7/sum.o  gcc -pthread -shared build/temp.linux-x86_64-2.7/sum.o  -o /root/cpython/test/sum.so
  编译完成之后可以导入到 python 中使用:
[u]复制代码[/u] 代码如下:
[root@v5254085f259 test]# python  ActivePython 2.7.2.5 (ActiveState Software Inc.) based on  Python 2.7.2 (default, Jun 24 2011, 11:24:26)  [GCC 4.0.2 20051125 (Red Hat 4.0.2-8)] on linux2  Type "help", "copyright", "credits" or "license" for more information.  >>> import pyximport; pyximport.install()  >>> import sum  >>> sum.sum(1,3)
  下面来进行一个简单的性能比较:     清单 9. Cython 测试代码
[u]复制代码[/u] 代码如下:
from time import time  def test(int n):         cdef int a =0         cdef int i         for i in xrange(n):                 a+= i         return a  t = time()  test(10000000)  print "total run time:"  print time()-t
  测试结果:
[u]复制代码[/u] 代码如下:
[GCC 4.0.2 20051125 (Red Hat 4.0.2-8)] on linux2  Type "help", "copyright", "credits" or "license" for more information.  >>> import pyximport; pyximport.install()  >>> import ctest  total run time:  0.00714015960693
  清单 10. Python 测试代码
[u]复制代码[/u] 代码如下:
from time import time  def test(n):         a =0;         for i in xrange(n):                 a+= i         return a  t = time()  test(10000000)  print "total run time:"  print time()-t  [root@v5254085f259 test]# python test.py  total run time:  0.971596002579
  从上述对比可以看到使用 Cython 的速度提高了将近 100 多倍。 总结     本文初步探讨了 python 常见的性能优化技巧以及如何借助工具来定位和分析程序的性能瓶颈,并提供了相关可以进行性能优化的工具或语言,希望能够更相关人员一些参考。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部