對python開發者來說,相信大家對Jetbrains出的python編輯器PyCharm應該都有了解。對我自己來說,每天專案中都在用。自從半年前從C#轉到python之後直到現在依舊還在適應,適應這門語言,適應編輯器(不過也老懷戀CSharp和VS了,MS大法也很好!)。
這小半年下來發現其實寫寫python也還行的:
- 語言本身的表達性很好,非常簡潔。個人很喜歡python的
裝飾器
,做一些橫向的複用效果非常好。 - 有活躍的開源社群,各種開源框架、開源庫。
幾個月的python碼下來,也養成了一些壞毛病,不管有意識還是無意識的經常很想把一大坨邏輯用一行程式碼解決,並不太關心程式碼的效率,再加上有python語言的效率本來就很差
這條被大家說爛掉的觀點加持,更加有恃無恐,呵呵。反過來想想,在coding的過程中多權衡,多嘗試一些更好的方式,邊寫邊重構才更能幫助你更好的coding和成長吧,而且在整個過程中有很多的樂趣,適當培養一些對程式碼的潔癖
還是棒棒噠。
差點都跑的沒背影了,言歸正傳。在寫程式碼的過程中如果碰到需要對程式碼執行效率權衡的話,能夠量化的做一些profile就更好了,常用的一些方式有藉助一些像profile
、hotshot
、timeit
來手動的做一些測量,不過這樣需搞有一些缺點:
- 需要手動寫一些測試的程式碼;
- 需要對輸出的結果進行一定的排版和美化,方便閱讀;
- 收集的資訊有限
鏘鏘鏘,終於輪到主角出場了。
PyCharm4.5中加入了一個新的功能 :Python Profiler
,只需要執行Run | Profile…就能使用,預設支援使用cProfile
,提供兩種檢視:Statistics
和Call Graph
:
兩種檢視下面顯示的內容是一樣的,包含函式被呼叫所執行的時間,次數等,只不過在”Call Graph“檢視下面,程式碼執行過程中各個函式被呼叫的層次關係都被完美的顯示出來,按呼叫耗時縱向排列,而且還輔以警告的顏色來進行提示。在各個節點上點選右鍵能夠看到Navigate to Source
的操作,點選能夠導航到相應的原始碼處,非常方便檢視程式碼。
在這裡我們以二叉查詢樹
為例,展示一些比如像二叉樹查詢、遍歷等基本操作在python profiler裡面執行的效果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
import time class Node(object): def __init__(self, data, left, right): self.data = data self.left = left self.right = right def show(self): return self.data class BSTree(object): def __init__(self): self.root = None def insert(self, data): temp_node = Node(data, None, None) if self.root is None: self.root = temp_node else: current_node = self.root while True: parent_node = current_node if data < current_node.data: current_node = current_node.left if current_node is None: parent_node.left = temp_node break else: current_node = current_node.right if current_node is None: parent_node.right = temp_node break def get_min(self): current_node = self.root while current_node.left is not None: current_node = current_node.left return current_node.data def get_max(self): current_node = self.root while current_node.right is not None: current_node = current_node.right return current_node.data def find(self, data): current_node = self.root while current_node is not None: if current_node.data == data: return current_node elif data < current_node.data: current_node = current_node.left else: current_node = current_node.right return None |
測試程式碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
from BSTree import BSTree import random def build_bst_tree(num): bst_tree = BSTree() source = list(xrange(1, num)) while num > 0 and source: data = random.choice(source) source.remove(data) bst_tree.insert(data) num -= 1 return bst_tree def in_order(node): node_str = "" if node is not None: in_order(node.left) print node.show(), in_order(node.right) my_bst_tree = build_bst_tree(500) in_order(my_bst_tree.root) my_bst_tree.get_min() my_bst_tree.get_max() my_bst_tree.find(123) |
依次點選選單 Run | Profile… 會生成並開啟一個xxxx.pstat
的Tab,裡面就是分別按Statistics
和Call graph
兩種檢視展示的profile結果:
在profile的結果中我們能夠看到,整個檔案執行共耗時13ms,二叉樹遍歷in_order
和二叉樹生成函式build_bst_tree
基本佔了大部分執行的時間,佔用的時間越長,節點的顏色越深,還是比較體貼的小功能。
我們對尋找二叉樹最大值節點的函式get_max
稍稍修改一下,在函式體裡面加一句time.sleep(5)
的邏輯,拖延一下執行的時間:
1 2 3 4 5 6 |
def get_max(self): time.sleep(5) current_node = self.root while current_node.right is not None: current_node = current_node.right return current_node.data |
現在再來看一下修改之後的profile的結果:
我們能夠看到,在get_max
的函式邏輯中加入5s的延遲之後,整個profie的結果也發生了一些改變,相應節點的時間耗時時間發生了變化,基本上增加了5s的時間.同時也能清晰的看到時間變長的原因是因為get_max
裡面呼叫了time.sleep()
,而且時間過長的節點比如get_max
也相應變成了紅色,用來警示。
好吧,就說到這裡,僅僅是粗略的介紹了一下PyCharm裡面這個新加的功能,希望能給大家一個初步印象,我相信多加利用這個方便到沒朋友的功能一定能幫助我們改善自己的程式碼。