[英]Python profiling
我在Python中編寫了幾個用於生成階乘的模塊,我想測試運行時間。 我在這里找到了一個分析的例子,我使用該模板來分析我的模塊:
import profile #fact
def main():
x = raw_input("Enter number: ")
profile.run('fact(int(x)); print')
profile.run('factMemoized(int(x)); print')
def fact(x):
if x == 0: return 1
elif x < 2: return x
else:
return x * fact(x-1)
def factMemoized(x):
if x == 0: return 1
elif x < 2: return x
dict1 = dict()
dict1[0] = 1
dict1[1] = 1
for i in range (0, x+1):
if dict1.has_key(i): pass
else: dict1[i] = i * dict1[i-1]
return dict1[x]
if __name__ == "__main__":
main()
但是,我收到以下錯誤:
Enter number: 10
Traceback (most recent call last):
File "fact.py", line 32, in <module>
main()
File "fact.py", line 7, in main
profile.run('fact(int(x)); x')
File "C:\Python27\lib\profile.py", line 70, in run
prof = prof.run(statement)
File "C:\Python27\lib\profile.py", line 447, in run
return self.runctx(cmd, dict, dict)
File "C:\Python27\lib\profile.py", line 453, in runctx
exec cmd in globals, locals
File "<string>", line 1, in <module>
NameError: name 'x' is not defined
知道我在這里做錯了嗎? TIA! 〜克雷格
正如John Gaines Jr.所說, profile.run()
有一些范圍問題。 但是,您可以將runctx
與globals()和locals()一起使用並顯式提供上下文:
profile.runctx('fact(int(x)); print', globals(), locals())
明確比隱含更好:)
探查器接收一個他試圖解釋的字符串。 你的字符串是profile.run('fact(int(x)); print')
, x
里面的變量只是字符串的一部分,無法解析為變量。 您必須將其值復制到字符串中才能使其工作。 嘗試這個:
profile.run('fact(int(%s)); print' % x)
profile.run('factMemoized(int(%s)); print' % x)
編輯(刪除我的“答案”,因為Petr Viktorin更有意義)。 但是留下解釋為什么它不像預期的那樣有效。
查看profile.py(Python 2.7.2)中的代碼,我看到類Profile的方法如下:
def run(self, cmd):
import __main__
dict = __main__.__dict__
return self.runctx(cmd, dict, dict)
def runctx(self, cmd, globals, locals):
self.set_cmd(cmd)
sys.setprofile(self.dispatcher)
try:
exec cmd in globals, locals
finally:
sys.setprofile(None)
return self
runctx()中的exec語句正在為全局和本地字典提供__main__.__dict__
,因此profile.run()只能解析在正在運行的應用程序的頂級字典中定義的變量。
您可以使用Region Profiler直接分析您的代碼。 您的代碼段如下所示:
import region_profiler as rp # pip install region-profiler
rp.install()
def main():
x = raw_input("Enter number: ")
fact(int(x)) # note: direct call
factMemoized(int(x))
@rp.func(asglobal=True)
def fact(x):
if x == 0: return 1
elif x < 2: return x
else:
return x * fact(x-1)
@rp.func(asglobal=True)
def factMemoized(x):
if x == 0: return 1
elif x < 2: return x
dict1 = dict()
dict1[0] = 1
dict1[1] = 1
for i in range (0, x+1):
if dict1.has_key(i): pass
else: dict1[i] = i * dict1[i-1]
return dict1[x]
if __name__ == "__main__":
main()
樣本輸出:
name total % of total count min average max
---------------- -------- ---------- ----- -------- -------- --------
<main> 3.601 s 100.00% 1 3.601 s 3.601 s 3.601 s
. fact() 863 us 0.02% 1 863 us 863 us 863 us
. factMemoized() 73.12 us 0.00% 1 73.12 us 73.12 us 73.12 us
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.