2011-07-10 72 views
2

我剛剛開始剖析我的代碼,並且感到困惑,爲什麼cProfile給出的流逝時間與使用time.time()給出的時間相差太遠。Python配置文件陷阱

# Python 2.7.2 

import cProfile 

def f(n): 
    G = (i for i in xrange(n)) 
    sum = 0 
    for i in G: 
     sum += i 

num = 10**6 

cProfile.run('f(num)') 

這給出2.648秒

用了time.time

然而,() 1000004函數調用,我得到0.218000173569秒

import time 

x = time.time() 
f(num) 
print time.time() - x 

從我讀過,我猜這可能是因爲cProfile的開銷。是否有任何關於cProfile時序可能非常關閉的常規提示,或者獲得更準確時序的方法?

回答

3

分析的重點是找出你的程序的部分花費大部分時間,因此最需要注意。如果90%的時間被一個函數使用,你應該在那裏看看如何讓這個函數更有效率。無論整個運行需要10秒還是1000秒。

也許分析器給你的最重要的信息是被調用的次數。爲什麼這很有用,它可以幫助你找到經常不必要地調用東西的地方,尤其是如果你有嵌套循環或調用其他函數的許多函數。分析器可以幫助你追蹤這些東西。

分析開銷不可避免,而且很大。但讓事件探查器完成它所做的事情要比在整個地方插入自己的計時和打印語句要容易得多。

+0

「如果90%的時間被一個功能使用......」 - 我主要的擔心並不是確切的時間花費,而是關於相對時間。我可以想象,看起來90%的時間實際上佔1%。我明白這涉及到錯綜複雜的問題,但我想知道是否有有用的啓發式方法,比如「某些類型的操作由於某種原因通常會在探查器中膨脹時間」。 – rallen

+0

@rallen:獲得花費的時間百分比(而不是絕對時間)正是我試圖創造的點。在使用分析器時,您不應該依賴絕對時間,因爲所分析的各個組件的列出時間之間的關係是如此之多。請注意,通常,人們使用分析器來檢查比您的示例更復雜的函數。 –

+0

@rallen:至於錯綜複雜的剖析器數字,以便隱藏真正的瓶頸,或者快速部分看起來像是一個瓶頸:我不認爲你會在任何你可能寫的東西中遇到這種情況。我不能說它永遠不會發生,但它不是我曾經有過理由擔心的事情。如果你碰巧遇到了似乎以令人難以置信的或令人難以置信的腥意方式進行描述的東西,那麼請將* *作爲Stack Overflow或comp.lang.python問題。 ;) –

1

請注意,cProfile爲您提供了CPU time,但使用time.time()會爲您提供流逝的時間(這不是您想要的)。

也許你可以嘗試使用unix time程序。

➜ sandbox /usr/bin/time -p python profiler.py 

real   0.17 
user   0.14 
sys   0.01 

的CPU時間應該是用戶+ SYS