2009-02-15 29 views
73

Tôi đang cố gắng tìm hiểu thời gian thực hiện câu lệnh Python, vì vậy tôi đã xem trực tuyến và thấy rằng thư viện chuẩn cung cấp mô-đun có tên là timeit mà nội dung thực hiện chính xác rằng:Nhận "tên toàn cầu 'foo' không được xác định" với thời gian của Python

import timeit 

def foo(): 
    # ... contains code I want to time ... 

def dotime(): 
    t = timeit.Timer("foo()") 
    time = t.timeit(1) 
    print "took %fs\n" % (time,) 

dotime() 

Tuy nhiên, điều này tạo ra một lỗi:

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 3, in dotime 
    File "/usr/local/lib/python2.6/timeit.py", line 193, in timeit 
    timing = self.inner(it, self.timer) 
    File "<timeit-src>", line 6, in inner 
NameError: global name 'foo' is not defined 

tôi vẫn còn mới để Python và tôi không hiểu đầy đủ tất cả các vấn đề Phạm vi nó có, nhưng Tôi không biết tại sao đoạn mã này không hoạt động. Có suy nghĩ gì không?

Trả lời

82

Thay đổi dòng này:

t = timeit.Timer("foo()") 

Để này:

t = timeit.Timer("foo()", "from __main__ import foo") 

Kiểm tra các liên kết mà bạn cung cấp ở dưới cùng rất.

To give the timeit module access to functions you define, you can pass a setup parameter which contains an import statement:

Tôi vừa thử nghiệm trên máy tính của mình và làm việc với các thay đổi.

+20

Nó hoạt động! Tuy nhiên, đây là một thiết kế giao diện khá ngu ngốc nếu tôi có cả hai cung cấp lệnh tôi muốn thời gian như một chuỗi và nhập khẩu các mô-đun __main__ cho nó để làm việc. –

+2

Việc đặt tên Python là hoàn toàn điên rồ với tôi. Tôi cho rằng nó có ý nghĩa đối với một loại tâm trí nào đó, nhưng cái trí óc đó không phải là thứ mà tôi tình cờ có được. Cảm ơn $ DEITY cho Ruby, trong trường hợp của tôi. – womble

+4

womble, đây là một wart, không phải là một vấn đề không gian tên python chung. Chủ đề chính: http://writeonly.wordpress.com/2008/09/12/using-python-timeit-to-time-functions/ có liên kết đến các cuộc thảo luận khác về việc này. –

8
t = timeit.Timer("foo()", "from __main__ import foo") 

Vì thời gian không có nội dung của bạn trong phạm vi.

18

Bạn có thể thử hack này:

import timeit 

def foo(): 
    print 'bar' 

def dotime(): 
    t = timeit.Timer("foo()") 
    time = t.timeit(1) 
    print "took %fs\n" % (time,) 

import __builtin__ 
__builtin__.__dict__.update(locals()) 

dotime() 
+1

Tấn công này rất tuyệt nếu bạn cần mã thiết lập phức tạp. –

+0

Tốt hơn so với thay thế mã khởi động được đưa ra trong các câu trả lời khác (tức là tốt hơn 't = timeit.Timer (" foo() "," từ __main__ import foo ")'). Đặc biệt nếu bạn muốn thử nghiệm một số chức năng khác nhau, nó sẽ tiết kiệm được rất nhiều đánh máy! –

+1

Tôi có khoảng 20 lần nhập, vì vậy việc chuyển chúng thành đối số sẽ nhanh chóng bị lộn xộn. Hack này là tuyệt vời! – kramer65

0

thêm vào thiết lập của bạn "thisfile nhập khẩu;"

sau đó khi bạn gọi hàm thiết lập myfunc() sử dụng "thisfile.myfunc()"

ví dụ: "thisfile.py"

def myfunc(): 

return 5 

def testable(par): 

pass 



t=timeit.timeit(stmt="testable(v)",setup="import thisfile; v=thisfile.myfunc();").repeat(10) 

print(t) 
4

Bạn có thể sử dụng globals=globals()

t = timeit.Timer("foo()", globals=globals()) 

Từ documentation:

Another option is to pass globals() to the globals parameter, which will cause the code to be executed within your current global namespace. This can be more convenient than individually specifying imports

+1

Chỉ hoạt động với Python 3. 'globals' không phải là tham số cho' timeit' của Python 2 –

Các vấn đề liên quan