2010-06-28 43 views
2

您好專家Pythonists,我開始使用cProfile,以便我的程序有一個更詳細的時間信息。但是,這對我來說是相當令人不安的,因爲這有很大的開銷。任何想法爲什麼cProfile報告7秒,而時間模塊僅在下面的代碼中報告2秒?在Python cProfile中有嚴重的開銷嗎?

# a simple function 

def f(a, b): 
c = a+b 

# a simple loop 
def loop(): 
for i in xrange(10000000): 
    f(1,2) 

# timing using time module 
# 2 seconds on my computer 
from time import time 
x = time() 
loop() 
y = time() 
print 'Time taken %.3f s.' % (y-x) 

# timing using cProfile 
# 7 seconds on my computer 
import cProfile 
cProfile.runctx('loop()', globals(), locals()) 

回答

3

因爲它做了很多工作? time只是整個操作的時間,而cProfile在儀表下運行,所以它可以得到詳細的分解。顯然,分析並不意味着在生產中使用,所以2.5倍的開銷似乎是一個小的代價。

+0

此外,函數非常微不足道,因此分析器似乎佔用了大量相對於總運行時間條款。 – 2010-06-28 18:03:53

+0

感謝您的回覆。 如果我將循環()中的迭代次數從10百萬增加到1億次,則時序線性變化!時間模塊花了20s,cProfile花了70s。如果cProfile花費更長的時間運行,我不會想,但是報告的時間(即在代碼中花費的實際時間)應該排除開銷。有沒有辦法校準cProfile(因爲我只對在代碼中花費的實際時間感興趣)? – user378289 2010-06-28 18:25:30

+1

@xqx:不是我所知道的。分析可以讓您瞭解程序不同部分的相關性能,但不適用於生產性能報告。 – 2010-07-02 19:55:06

1

函數f返回非常快。當您使用cProfile時,一次致電f的時間不準確,因爲時間太短以至於與測量時間的誤差相差無幾。用於測量時間差異的時鐘可能只能精確到0.001秒。所以每次測量的誤差可能比您嘗試測量的時間大幾個數量級。做1e7次,你有假結果。 (關於此更多的討論參見http://docs.python.org/library/profile.html#limitations

請注意,如果你改變了代碼,使用

def f(a, b): 
for i in xrange(int(1e4)):  
    c = a+b 

# a simple loop 
def loop(): 
for i in xrange(int(1e3)): 
    f(1,2) 

Time taken 0.732 s. 
     1003 function calls in 0.725 CPU seconds 

    Ordered by: standard name 

    ncalls tottime percall cumtime percall filename:lineno(function) 
     1 0.000 0.000 0.725 0.725 <string>:1(<module>) 
    1000 0.723 0.001 0.723 0.001 test.py:4(f) 
     1 0.001 0.001 0.725 0.725 test.py:9(loop) 
     1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 

你正在做同樣的環路數,但每致電f需要更長的時間。這可以減少每次測量的誤差。 (歸因於每個呼叫的時間爲f包含的錯誤現在不會像測量的總時間那樣大)。

+0

嗨unutbu。在您的示例中,使用和不使用輪廓儀所用的時間非常接近,即0.732s和0.725s。除了你提到的可能引入的錯誤之外,我認爲在我的例子中函數f被調用了更多次(1e7,而不是你的例子中的1e3),因此具有更多的分析成本。 – user378289 2010-07-05 17:37:25

相關問題