像老大一样优化 Python

我们应该忘掉一些小的效率问题,在 97% 的情况下是这么说的:过早优化是万恶之源。—— Donald Knuth

如果不首先想想这句Knuth的名言,就开始进行优化工作是不明智的。可是,你很快写出来加入一些特性的代码,可能会很丑陋,你需要注意了。这篇文章就是为这时候准备的。

那么接下来就是一些很有用的工具和模式来快速优化Python。它的主要目的很简单:尽快发现瓶颈,修复它们并且确认你修复了它们。

写一个测试

在你开始优化前,写一个高级测试来证明原来代码很慢。你可能需要采用一些最小值数据集来复现它足够慢。通常一两个显示运行时秒的程序就足够处理一些改进的地方了。

有一些基础测试来保证你的优化没有改变原有代码的行为也是很必要的。你也能够在很多次运行测试来优化代码的时候稍微修改这些测试的基准。

那么现在,我们来来看看优化工具把。

简单的计时器

计时器很简单,这是一个最灵活的记录执行时间的方法。你可以把它放到任何地方并且副作用很小。运行你自己的计时器非常简单,并且你可以将其定制,使它以你期望的方式工作。例如,你个简单的计时器如下:

import time

def timefunc(f):
    def f_timer(*args, **kwargs):
        start = time.time()
        result = f(*args, **kwargs)
        end = time.time()
        print f.__name__, 'took', end - start, 'time'
        return result
    return f_timer

def get_number():
    for x in xrange(5000000):
        yield x

@timefunc
def expensive_function():
    for x in get_number():
        i = x ^ x ^ x
    return 'some result!'

# prints "expensive_function took 0.72583088875 seconds"
result = expensive_function()

当然,你可以用上下文管理来让它功能更加强大,添加一些检查点或者一些其他的功能:

import time

class timewith():
    def __init__(self, name=''):
        self.name = name
        self.start = time.time()

@property
    def elapsed(self):
        return time.time() - self.start

def checkpoint(self, name=''):
        print '{timer} {checkpoint} took {elapsed} seconds'.format(
            timer=self.name,
            checkpoint=name,
            elapsed=self.elapsed,
        ).strip()

def __enter__(self):
        return self

def __exit__(self, type, value, traceback):
        self.checkpoint('finished')
        pass

def get_number():
    for x in xrange(5000000):
        yield x

def expensive_function():
    for x in get_number():
        i = x ^ x ^ x
    return 'some result!'

# prints something like:
# fancy thing done with something took 0.582462072372 seconds
# fancy thing done with something else took 1.75355315208 seconds
# fancy thing finished took 1.7535982132 seconds
with timewith('fancy thing') as timer:
    expensive_function()
    timer.checkpoint('done with something')
    expensive_function()
    expensive_function()
    timer.checkpoint('done with something else')

# or directly
timer = timewith('fancy thing')
expensive_function()
timer.checkpoint('done with something')

推荐阅读:

《Python开发技术详解》.( 周伟,宗杰).[高清PDF扫描版+随书视频+代码]

Python脚本获取Linux系统信息

Python 的详细介绍请点这里
Python 的下载地址请点这里

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/3f1795f857723ade6e76ecfe3ae2d36b.html