歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

像老大一樣優化 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')

Copyright © Linux教程網 All Rights Reserved