1. 程式人生 > >python高階-程式碼優化

python高階-程式碼優化

一、函式返回值快取

class memoization:
    known = dict()
    '''用這個裝飾耗時0.5秒'''
    def __init__(self, fn):
        self.fn = fn

    def __call__(self, *args):
        if args not in self.known:
            self.known[args] = self.fn(*args)
        return self.known[args]

@memoization
def 
fbnq(n):
assert(n >= 0), u'n必須大於等於0' return n if n in (0, 1) else fbnq(n - 1) + fbnq(n - 2) if __name__ == '__main__': from timeit import Timer t = Timer('fbnq(10)', 'from __main__ import fbnq') print(t.timeit())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

二、函式查詢表

(一)用列表或連結串列做查詢表

注意:在這種情況下,連結串列比普通列表效能高,但是連結串列的型別也會對效能產生影響。

(二)用字典做查詢表

注意:只要每次生成不同的鍵,這個演算法才是有效的。但是,隨著字典的規模不斷增大,碰撞頻繁,效能會下降。

(三)二分查詢

注意:這種演算法只有在有序的條件下才能使用。處理長的列表,效率會很高。

三、列表表示式和生成器

列表推導式詳見:列表推導式
生成器詳見:生成器

四、ctypes

(一)介紹

ctypes庫可以直接讓開發者進入python底層。藉助C語言的力量去開發。
這個庫只有官方版本(Cpython)才有。

(二)載入自定義ctypes

載入一個系統庫,這個庫不需要自己手寫C函式。

隨機產生100w個隨機數:

import time
import random
from ctypes import cdll

# libc = cdll.msvcrt  # windows系統
libc = cdll.LoadLibrary('libc.so.6')  # linux系統

init = time.clock()
[random.randrange(1, 100) for x in xrange(1000000)]
print 'python version:%s seconds' % (time.clock() - init)

init = time.clock()
[(libc.rand() % 100) for x in xrange(1000000)]
print 'C version:%s seconds' % (time.clock() - init)
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

五、字串連線

word_list = ['apple', 'banana', 'orange']
full_str = ''
for word in word_list:
    full_str += word
# 下面比上面更容易閱讀,書寫方便,記憶體和時間消耗更少。
''.join(word_list)
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

六、python小竅門(內部運作方式)

(一)成員關係測試

for a in b 時,這個b儘可能為set或者dict
    
  • 1

(二)不要重複造輪子

  • itertools 詳解
  • collections 詳解
  • 內建函式:map()
    推薦使用。。。

(三)學會使用佇列

(四)1比True好

        <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/markdown_views-ea0013b516.css">
            </div>

一、函式返回值快取

class memoization:
    known = dict()
    '''用這個裝飾耗時0.5秒'''
    def __init__(self, fn):
        self.fn = fn

    def __call__(self, *args):
        if args not in self.known:
            self.known[args] = self.fn(*args)
        return self.known[args]

@memoization
def fbnq(n):
    assert(n >= 0), u'n必須大於等於0'
    return n if n in (0, 1) else fbnq(n - 1) + fbnq(n - 2)

if __name__ == '__main__':
    from timeit import Timer
    t = Timer('fbnq(10)', 'from __main__ import fbnq')
    print(t.timeit())
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

二、函式查詢表

(一)用列表或連結串列做查詢表

注意:在這種情況下,連結串列比普通列表效能高,但是連結串列的型別也會對效能產生影響。

(二)用字典做查詢表

注意:只要每次生成不同的鍵,這個演算法才是有效的。但是,隨著字典的規模不斷增大,碰撞頻繁,效能會下降。

(三)二分查詢

注意:這種演算法只有在有序的條件下才能使用。處理長的列表,效率會很高。

三、列表表示式和生成器

列表推導式詳見:列表推導式
生成器詳見:生成器

四、ctypes

(一)介紹

ctypes庫可以直接讓開發者進入python底層。藉助C語言的力量去開發。
這個庫只有官方版本(Cpython)才有。

(二)載入自定義ctypes

載入一個系統庫,這個庫不需要自己手寫C函式。

隨機產生100w個隨機數:

import time
import random
from ctypes import cdll

# libc = cdll.msvcrt  # windows系統
libc = cdll.LoadLibrary('libc.so.6')  # linux系統

init = time.clock()
[random.randrange(1, 100) for x in xrange(1000000)]
print 'python version:%s seconds' % (time.clock() - init)

init = time.clock()
[(libc.rand() % 100) for x in xrange(1000000)]
print 'C version:%s seconds' % (time.clock() - init)
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

五、字串連線

word_list = ['apple', 'banana', 'orange']
full_str = ''
for word in word_list:
    full_str += word
# 下面比上面更容易閱讀,書寫方便,記憶體和時間消耗更少。
''.join(word_list)
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

六、python小竅門(內部運作方式)

(一)成員關係測試

for a in b 時,這個b儘可能為set或者dict
  
  • 1

(二)不要重複造輪子

  • itertools 詳解
  • collections 詳解
  • 內建函式:map()
    推薦使用。。。

(三)學會使用佇列

(四)1比True好

        <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/markdown_views-ea0013b516.css">
            </div>