python调优(零)

Python调优

一直给大家分享机器学习呀、算法呀、数学呀等等的,其实工程的东西说的比较少,本文介绍Python的性能优化,再好的算法也需要优雅的调优将来才能走的更远,对于算法来说Python几乎是天天不离手,所以对于Python的理解必须要强过其他人,否则你怎么保证你的程序是最好呢?

cProfile

首先我们来认识一个工具,你如果没有做过Python调优你肯定没有用过,cProfile是一个可以发现你程序性能的工具,接下来我们就来学习这个工具的用法。

1.模块 profile:这个模块是完全使用 Python编写的,给程序执行增加了很大的开销 。 这 个模块之所以出现在标准库中,原因在于其强大的平台支持和易于扩展 。

2.模块 cProfile:这是主要的剖析模块,其接口与 profile 相同 。 这个模块是使用 C语言编写的,因此开销很小,适合用作通用剖析器。

首先我们来看一个例子:

import time

def add_1():
    time.sleep(0.2)
    return 1

def add_2():
    return 2

sum_num = 0
for i in range(100):
    sum_num += add_1()
    sum_num += add_2()
    if sum_num >= 100:
        print "success"
        break

代码十分简单,就是不同就是,add_1函数有一个sleep的操作,其实是想体现出性能问题,接下来这段代码的输出是怎么样的呢?如下就是运行这段代码性能分析的命令。

 python -m cProfile effect.py
   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.001    0.001    6.878    6.878 effect.py:1(<module>)
       34    0.000    0.000    6.877    0.202 effect.py:4(add_1)
       34    0.000    0.000    0.000    0.000 effect.py:9(add_2)
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
        1    0.000    0.000    0.000    0.000 {range}
       34    6.876    0.202    6.876    0.202 {time.sleep}

可以看出,上面的命令输出了如下的几列指标,那么我们来解释这些指标分别代表什么意思?

ncalls:函数被调用的次数。
tottime: 执行函数花费的总时间,不考虑其他函数调用 。
cumtime: 执行函数花费的总时间 ,考虑其他函数调用 。
percall: 单次函数调用花费的时间一一可通过将总时间除以调用次数得到。
filename:lineno:文件名和相应的行号。 调用 C语言扩展模块时,不包含这种信息

是不是非常清晰,time.sleep这行代码花费了大部分的时间,那么我们做当个python脚本的分析的时候也能发现我们代码中的一些问题,当然还有其他的方式可以实现,例如你可以使用计算时间的方式发现每行代码的执行时间,就是实现可能会比较繁琐。

你可能还有另外一个问题,那就是我的程序中可以调用类似这样的代码吗,我不想在程序的最外层执行这样的shell命令。

import cProfile

def add_1():
    time.sleep(0.2)
    return 1

cProfile.run("add_1()")

通过这样的方式能够测试一个函数的性能报告。

Cython

Cython是一种扩展 Python 的语言,这是通过支持给函数、变量和类声明类型来实现的 。 这 些类型声明让 Cython能够将 Python脚本编译成高效的 C语言代码 。Cython还可充 当 Python 和 C 语言之间的桥梁,因为它提供了易于使用的结构,让你能够编写到外部 C和 C++例程的接口。

Cython语法被设计成 Python语法的超集 。 在不做任何修改的情况下, Cython 就能够编译大 部分 Python模块( 例外的情况不多)。 Cython源代码文件的扩展名为.pyx,可使用命令 cython 编译成 C语言文件。

新建一个cpython.pyx

def hello():
    print "hello"

简单的不要不要的,下面我们来编一个这个文件。

cython hello .pyx

这个时候会产生另一文件,cpython.c。

gcc -shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing -lm -I venv/include/python2.7/ -o cpython.so cpython.c

以上这个过程,我们就将python源码变成了C代码,神奇吧,C的运行性能可是比python 块很多的。Cython的语法这里就不详细介绍了,希望大家了解以后能知道通过python能够编译生成C的代码从而提升性能的门路。

总结

本节介绍了一下python性能分析小工具,大家可以尝试,其实对于工具而言无非是知道和不知道的区别,了解就好,我们后面会介绍更多关于python优化的内容。

# coding  python 
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×