Làm thế nào để đo thời gian trôi qua trong Python?


1210

Điều tôi muốn là bắt đầu đếm thời gian ở đâu đó trong mã của mình và sau đó lấy thời gian đã qua, để đo thời gian cần thiết để thực hiện một vài chức năng. Tôi nghĩ rằng tôi đang sử dụng mô-đun thời gian sai, nhưng các tài liệu chỉ gây nhầm lẫn cho tôi.

import timeit

start = timeit.timeit()
print("hello")
end = timeit.timeit()
print(end - start)

Câu trả lời:


1456

Nếu bạn chỉ muốn đo thời gian đồng hồ treo tường trôi qua giữa hai điểm, bạn có thể sử dụng time.time():

import time

start = time.time()
print("hello")
end = time.time()
print(end - start)

Điều này cho thời gian thực hiện trong vài giây.

Một tùy chọn khác kể từ 3.3 có thể là sử dụng perf_counterhoặc process_time, tùy thuộc vào yêu cầu của bạn. Trước 3,3 nên sử dụng time.clock(cảm ơn Amber ). Tuy nhiên, hiện không được chấp nhận:

Trên Unix, trả về thời gian của bộ xử lý hiện tại dưới dạng số dấu phẩy động được biểu thị bằng giây. Độ chính xác, và trên thực tế, chính là định nghĩa về ý nghĩa của thời gian xử lý của bộ xử lý thời gian, phụ thuộc vào chức năng C cùng tên.

Trên Windows, chức năng này trả về giây đồng hồ treo tường đã trôi qua kể từ lần gọi đầu tiên đến chức năng này, dưới dạng số dấu phẩy động, dựa trên chức năng Win32 QueryPerformanceCounter(). Độ phân giải thường tốt hơn một micro giây.

Không dùng nữa kể từ phiên bản 3.3 : Hành vi của chức năng này phụ thuộc vào nền tảng: sử dụng perf_counter()hoặc process_time()thay vào đó , tùy thuộc vào yêu cầu của bạn, để có hành vi được xác định rõ.


17
và trong micro giây, sử dụng datetime.time ()
Inca

110
(Đối với phép đo hiệu suất, time.clock()thực sự được ưa thích, vì nó không thể bị can thiệp nếu đồng hồ hệ thống bị rối, nhưng .time()hầu như không hoàn thành cùng một mục đích.)
Amber

4
Tôi nghĩ rằng python -mtimeit tốt hơn nhiều khi nó chạy nhiều lần hơn và nó được xây dựng như một cách bản địa để đo thời gian trong python
Visgean Sk Bacheloru

4
Có một cách hay để chuyển đổi thời gian ngoại lệ trong vài giây sang thứ gì đó như HH: MM :: SS không?
Danijel

12
@Danijel : print(timedelta(seconds=execution_time)). Mặc dù đó là một câu hỏi riêng biệt.
jfs

688

Sử dụng timeit.default_timerthay vì timeit.timeit. Cái trước cung cấp đồng hồ tốt nhất có sẵn trên nền tảng và phiên bản Python của bạn:

from timeit import default_timer as timer

start = timer()
# ...
end = timer()
print(end - start) # Time in seconds, e.g. 5.38091952400282

timeit.default_timer được gán cho time.time () hoặc time.clock () tùy thuộc vào HĐH. Trên Python 3.3+ default_timertime.perf_corer () trên tất cả các nền tảng. Xem Python - time.clock () so với time.time () - độ chính xác?

Xem thêm:


28
Câu trả lời tuyệt vời - sử dụng timeit sẽ tạo ra kết quả chính xác hơn rất nhiều vì nó sẽ tự động giải thích cho những thứ như thu gom rác và sự khác biệt của hệ điều hành
lkgarrison

1
Điều này cho thời gian tính bằng ms hay giây?
Katie

3
@KhushbooTiwari trong vài giây.
JFS

5
Tôi nghĩ rằng ghi chú này từ tài liệu chính thức cần phải được thêm vàodefault_timer() measurations can be affected by other programs running on the same machine, so the best thing to do when accurate timing is necessary is to repeat the timing a few times and use the best time. The -r option is good for this; the default of 3 repetitions is probably enough in most cases. On Unix, you can use time.clock() to measure CPU time.
KGS

1
@KGS: Đo lường hiệu suất rất khó khăn một cách tinh tế (rất dễ đánh lừa chính bạn). Có nhiều nhận xét khác có thể có liên quan ở đây. Thực hiện theo các liên kết trong câu trả lời. Bạn cũng có thể quan tâm đến perfmô-đun (không tồn tại tại thời điểm trả lời) cung cấp cùng một giao diện nhưng đôi khi nó khác với các timeitquyết định của mô-đun về cách đo hiệu suất thời gian.
jfs

129

Chỉ Python 3:

Vì time.clock () không được dùng trong Python 3.3 , nên bạn sẽ muốn sử dụng time.perf_counter()cho thời gian trên toàn hệ thống hoặc time.process_time()cho thời gian trên toàn quy trình, giống như cách bạn đã sử dụng time.clock():

import time

t = time.process_time()
#do some stuff
elapsed_time = time.process_time() - t

Chức năng mới process_timesẽ không bao gồm thời gian trôi qua trong khi ngủ.


28
Sử dụngtimeit.default_timer thay vì time.perf_counter. Cái trước sẽ chọn bộ hẹn giờ thích hợp để đo hiệu suất thời gian được điều chỉnh cho nền tảng và phiên bản Python của bạn. process_time()thực hiện không bao gồm thời gian trong khi ngủ và do đó nó không thích hợp để đo thời gian trôi qua.
jfs

2
Tôi đang sử dụng triển khai được đề xuất bởi Pierre, các giá trị được đưa ra trong vài giây?
ugotchi

Câu trả lời này có vẻ lạc đề (tốt, câu hỏi không cụ thể lắm). Có hai phép đo "thời gian": thời gian đồng hồ treo tường giữa hai điểm, mức tiêu thụ cpu của quy trình.
Franklin Piat

87

Đưa ra một chức năng mà bạn muốn thời gian,

kiểm tra:

def foo(): 
    # print "hello"   
    return "hello"

Cách dễ nhất để sử dụng timeitlà gọi nó từ dòng lệnh:

% python -mtimeit -s'import test' 'test.foo()'
1000000 loops, best of 3: 0.254 usec per loop

Đừng cố sử dụng time.timehoặc time.clock(ngây thơ) để so sánh tốc độ của các chức năng. Họ có thể đưa ra kết quả sai lệch .

Tái bút Không đặt báo cáo in trong một chức năng bạn muốn thời gian; nếu không thì thời gian đo sẽ phụ thuộc vào tốc độ của thiết bị đầu cuối .


65

Thật thú vị khi làm điều này với một trình quản lý bối cảnh tự động ghi nhớ thời gian bắt đầu khi vào một withkhối, sau đó đóng băng thời gian kết thúc khi thoát khỏi khối. Với một mẹo nhỏ, bạn thậm chí có thể có được một kiểm đếm thời gian trôi qua bên trong khối từ cùng một chức năng quản lý bối cảnh.

Thư viện lõi không có cái này (nhưng có lẽ nên có). Khi đã có, bạn có thể làm những việc như:

with elapsed_timer() as elapsed:
    # some lengthy code
    print( "midpoint at %.2f seconds" % elapsed() )  # time so far
    # other lengthy code

print( "all done at %.2f seconds" % elapsed() )

Dưới đây là contextmanager đang đủ để làm các trick:

from contextlib import contextmanager
from timeit import default_timer

@contextmanager
def elapsed_timer():
    start = default_timer()
    elapser = lambda: default_timer() - start
    yield lambda: elapser()
    end = default_timer()
    elapser = lambda: end-start

Và một số mã demo chạy được:

import time

with elapsed_timer() as elapsed:
    time.sleep(1)
    print(elapsed())
    time.sleep(2)
    print(elapsed())
    time.sleep(3)

Lưu ý rằng theo thiết kế của chức năng này, giá trị trả về elapsed()bị đóng băng khi thoát khỏi khối và các cuộc gọi tiếp theo sẽ trả về cùng thời lượng (khoảng 6 giây trong ví dụ về đồ chơi này).


2
Ví dụ về trình quản lý bối cảnh khác: dabeaz.blogspot.fr/2010/02/ Kẻ
Jérôme

1
@ Jérôme ví dụ hay - Tôi đã điều chỉnh nó thành một câu trả lời khác - stackoverflow.com/a/41408510/243392
Brian Burns

62

Đo thời gian tính bằng giây:

from timeit import default_timer as timer
from datetime import timedelta

start = timer()
end = timer()
print(timedelta(seconds=end-start))

Đầu ra :

0:00:01.946339

1
Đây là câu trả lời ngắn gọn nhất với đầu ra sạch nhất.
Dave Liu

56

Tôi thích điều này. timeitdoc quá khó hiểu

from datetime import datetime 

start_time = datetime.now() 

# INSERT YOUR CODE 

time_elapsed = datetime.now() - start_time 

print('Time elapsed (hh:mm:ss.ms) {}'.format(time_elapsed))

Lưu ý rằng không có bất kỳ định dạng nào đang diễn ra ở đây, tôi chỉ viết hh:mm:ssvào bản in để người ta có thể diễn giảitime_elapsed


Tôi đã nói rằng timeit tính toán thời gian của CPU, liệu datetime cũng có tính đến thời gian CPU được sử dụng không? Đây có phải là điều tương tự?
Sreehari R

3
Thật nguy hiểm khi đo thời gian đã trôi qua theo cách này vì datetime.now () có thể thay đổi giữa hai cuộc gọi vì các lý do như đồng bộ hóa thời gian mạng, chuyển đổi tiết kiệm ánh sáng ban ngày hoặc người dùng xoay vòng đồng hồ.
dùng1318499

45

Đây là một cách khác để làm điều này:

>> from pytictoc import TicToc
>> t = TicToc() # create TicToc instance
>> t.tic() # Start timer
>> # do something
>> t.toc() # Print elapsed time
Elapsed time is 2.612231 seconds.

So sánh với cách truyền thống:

>> from time import time
>> t1 = time()
>> # do something
>> t2 = time()
>> elapsed = t2 - t1
>> print('Elapsed time is %f seconds.' % elapsed)
Elapsed time is 2.612231 seconds.

Cài đặt:

pip install pytictoc

Tham khảo trang PyPi để biết thêm chi tiết.


13
Sẽ là tốt để giải thích lợi thế của việc sử dụng thư viện này so với các phương pháp khác.
hlg

Các chức năng lồng nhau thực sự bị hỏng. Tôi đã mở một vấn đề mô tả vấn đề trong mã là gì nhưng repo đã không được duy trì trong một năm vì vậy tôi sẽ không mong đợi một sự thay đổi.
PetarMI

Tôi thấy việc làm tổ hơi khó hiểu. Nếu tôi tình cờ t.tic()bị chôn vùi trong mã, thì nhà phát triển phải giữ một danh sách tinh thần về vị trí trong chuỗi mà tôi mong đợi. Bạn có thấy mình đang thiết lập tổ hoặc chỉ nhiều tictocs không?
ScottieB

1
@PetarMI: FYI, tôi vừa sửa vấn đề với ttictoc. Tôi đã có một mớ hỗn độn, nhưng bây giờ nó sẽ tốt thôi.
H. Sánchez

33

Dưới đây là những phát hiện của tôi sau khi trải qua nhiều câu trả lời tốt ở đây cũng như một vài bài viết khác.

Đầu tiên, nếu bạn đang tranh luận giữa timeittime.time, timeitcó hai ưu điểm:

  1. timeit chọn bộ hẹn giờ tốt nhất có sẵn trên phiên bản HĐH và Python của bạn.
  2. timeit vô hiệu hóa bộ sưu tập rác, tuy nhiên, đây không phải là thứ bạn có thể muốn hoặc không muốn.

Bây giờ vấn đề là nó timeitkhông đơn giản để sử dụng vì nó cần thiết lập và mọi thứ trở nên xấu xí khi bạn có một loạt các nhập khẩu. Lý tưởng nhất, bạn chỉ muốn một trang trí hoặc sử dụngwith khối và đo thời gian. Thật không may, không có gì tích hợp sẵn cho việc này để bạn có hai tùy chọn:

Tùy chọn 1: Sử dụng thư viện thời gian

Bảng thời gian là một thư viện linh hoạt và rất đơn giản mà bạn có thể sử dụng chỉ trong một dòng mã sau khi cài đặt pip.

@timebudget  # Record how long this function takes
def my_method():
    # my code

Tùy chọn 2: Sử dụng mô-đun mã trực tiếp

Tôi đã tạo ra bên dưới mô-đun tiện ích nhỏ.

# utils.py
from functools import wraps
import gc
import timeit

def MeasureTime(f, no_print=False, disable_gc=False):
    @wraps(f)
    def _wrapper(*args, **kwargs):
        gcold = gc.isenabled()
        if disable_gc:
            gc.disable()
        start_time = timeit.default_timer()
        try:
            result = f(*args, **kwargs)
        finally:
            elapsed = timeit.default_timer() - start_time
            if disable_gc and gcold:
                gc.enable()
            if not no_print:
                print('"{}": {}s'.format(f.__name__, elapsed))
        return result
    return _wrapper

class MeasureBlockTime:
    def __init__(self,name="(block)", no_print=False, disable_gc=False):
        self.name = name
        self.no_print = no_print
        self.disable_gc = disable_gc
    def __enter__(self):
        self.gcold = gc.isenabled()
        if self.disable_gc:
            gc.disable()
        self.start_time = timeit.default_timer()
    def __exit__(self,ty,val,tb):
        self.elapsed = timeit.default_timer() - self.start_time
        if self.disable_gc and self.gcold:
            gc.enable()
        if not self.no_print:
            print('Function "{}": {}s'.format(self.name, self.elapsed))
        return False #re-raise any exceptions

Bây giờ bạn có thể đặt thời gian cho bất kỳ chức năng nào chỉ bằng cách đặt một trang trí trước nó:

import utils

@utils.MeasureTime
def MyBigFunc():
    #do something time consuming
    for i in range(10000):
        print(i)

Nếu bạn muốn phần thời gian của mã thì chỉ cần đặt nó vào trong withkhối:

import utils

#somewhere in my code

with utils.MeasureBlockTime("MyBlock"):
    #do something time consuming
    for i in range(10000):
        print(i)

# rest of my code

Ưu điểm:

Có một số phiên bản được hỗ trợ một nửa nổi xung quanh vì vậy tôi muốn chỉ ra một vài điểm nổi bật:

  1. Sử dụng bộ đếm thời gian từ timeit thay vì time.time vì những lý do được mô tả trước đó.
  2. Bạn có thể vô hiệu hóa GC trong thời gian nếu bạn muốn.
  3. Decorator chấp nhận các chức năng với các thông số được đặt tên hoặc không tên.
  4. Khả năng vô hiệu hóa in trong thời gian khối (sử dụng with utils.MeasureBlockTime() as tvà sau đó t.elapsed).
  5. Khả năng giữ gc kích hoạt cho thời gian khối.

28

Sử dụng time.timeđể đo lường thực thi cung cấp cho bạn thời gian thực hiện tổng thể của các lệnh bao gồm cả thời gian chạy của các quy trình khác trên máy tính của bạn. Đó là thời gian người dùng thông báo, nhưng sẽ không tốt nếu bạn muốn so sánh các đoạn mã / thuật toán / hàm khác nhau / ...

Thêm thông tin về timeit:

Nếu bạn muốn có cái nhìn sâu sắc hơn về hồ sơ:

Cập nhật : Tôi đã sử dụng http://pythonhosted.org/line_profiler/ rất nhiều trong năm ngoái và thấy nó rất hữu ích và khuyên bạn nên sử dụng nó thay vì mô-đun hồ sơ Pythons.


19

Đây là một lớp hẹn giờ nhỏ trả về chuỗi "hh: mm: ss":

class Timer:
  def __init__(self):
    self.start = time.time()

  def restart(self):
    self.start = time.time()

  def get_time_hhmmss(self):
    end = time.time()
    m, s = divmod(end - self.start, 60)
    h, m = divmod(m, 60)
    time_str = "%02d:%02d:%02d" % (h, m, s)
    return time_str

Sử dụng:

# Start timer
my_timer = Timer()

# ... do something

# Get time string:
time_hhmmss = my_timer.get_time_hhmmss()
print("Time elapsed: %s" % time_hhmmss )

# ... use the timer again
my_timer.restart()

# ... do something

# Get time:
time_hhmmss = my_timer.get_time_hhmmss()

# ... etc

17

Các mô-đun cProfile và pstats python cung cấp hỗ trợ tuyệt vời để đo thời gian trôi qua trong một số chức năng nhất định mà không phải thêm bất kỳ mã nào xung quanh các chức năng hiện có.

Ví dụ: nếu bạn có tập lệnh python timeFiances.py:

import time

def hello():
    print "Hello :)"
    time.sleep(0.1)

def thankyou():
    print "Thank you!"
    time.sleep(0.05)

for idx in range(10):
    hello()

for idx in range(100):
    thankyou()

Để chạy trình lược tả và tạo số liệu thống kê cho tệp, bạn chỉ cần chạy:

python -m cProfile -o timeStats.profile timeFunctions.py

Điều này đang làm là sử dụng mô-đun cProfile để cấu hình tất cả các chức năng trong timeFiances.py và thu thập số liệu thống kê trong tệp timeStats.profile. Lưu ý rằng chúng tôi không phải thêm bất kỳ mã nào vào mô-đun hiện có (timeFiances.py) và điều này có thể được thực hiện với bất kỳ mô-đun nào.

Khi bạn có tệp thống kê, bạn có thể chạy mô-đun pstats như sau:

python -m pstats timeStats.profile

Điều này chạy trình duyệt thống kê tương tác cung cấp cho bạn rất nhiều chức năng tốt đẹp. Đối với trường hợp sử dụng cụ thể của bạn, bạn chỉ có thể kiểm tra số liệu thống kê cho chức năng của mình. Trong ví dụ kiểm tra số liệu thống kê cho cả hai chức năng cho chúng ta thấy như sau:

Welcome to the profile statistics browser.
timeStats.profile% stats hello
<timestamp>    timeStats.profile

         224 function calls in 6.014 seconds

   Random listing order was used
   List reduced from 6 to 1 due to restriction <'hello'>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
       10    0.000    0.000    1.001    0.100 timeFunctions.py:3(hello)

timeStats.profile% stats thankyou
<timestamp>    timeStats.profile

         224 function calls in 6.014 seconds

   Random listing order was used
   List reduced from 6 to 1 due to restriction <'thankyou'>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
      100    0.002    0.000    5.012    0.050 timeFunctions.py:7(thankyou)

Ví dụ giả không làm được gì nhiều nhưng cho bạn ý tưởng về những gì có thể được thực hiện. Phần tốt nhất về cách tiếp cận này là tôi không phải chỉnh sửa bất kỳ mã hiện có nào của mình để có được những con số này và rõ ràng là giúp ích cho việc định hình.


Tất cả điều này là tốt, nhưng AFAICT điều này vẫn đo thời gian CPU, không phải thời gian đồng hồ treo tường.
ShreevatsaR

1
Trên thực tế có một số nhầm lẫn; Theo mặc định, cProfile nhìn vào đồng hồ treo tường. Tôi đã nêu lên câu trả lời của bạn.
ShreevatsaR

FYI: Nếu bạn python -m pstats timeStats.profile ValueError: bad marshal data (unknown type code)kiểm tra phiên bản python của bạn, bạn đang chạy. Tôi đã nhận được điều này khi tôi chạy python3 -m cProfile...python -m pstats. Sai lầm của tôi nhưng đã cho tôi một giây, vì vậy, tôi muốn chia sẻ don't forget consistency. =)
JayRizzo

17

Đây là một trình quản lý bối cảnh khác cho mã thời gian -

Sử dụng:

from benchmark import benchmark

with benchmark("Test 1+1"):
    1+1
=>
Test 1+1 : 1.41e-06 seconds

hoặc, nếu bạn cần giá trị thời gian

with benchmark("Test 1+1") as b:
    1+1
print(b.time)
=>
Test 1+1 : 7.05e-07 seconds
7.05233786763e-07

điểm chuẩn :

from timeit import default_timer as timer

class benchmark(object):

    def __init__(self, msg, fmt="%0.3g"):
        self.msg = msg
        self.fmt = fmt

    def __enter__(self):
        self.start = timer()
        return self

    def __exit__(self, *args):
        t = timer() - self.start
        print(("%s : " + self.fmt + " seconds") % (self.msg, t))
        self.time = t

Được chuyển thể từ http://dabeaz.blogspot.fr/2010/02/context-manager-for-timing-benchmark.html


17

Sử dụng mô đun hồ sơ. Nó cho một hồ sơ rất chi tiết.

import profile
profile.run('main()')

nó xuất ra một cái gì đó như:

          5 function calls in 0.047 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    0.000    0.000 :0(exec)
        1    0.047    0.047    0.047    0.047 :0(setprofile)
        1    0.000    0.000    0.000    0.000 <string>:1(<module>)
        0    0.000             0.000          profile:0(profiler)
        1    0.000    0.000    0.047    0.047 profile:0(main())
        1    0.000    0.000    0.000    0.000 two_sum.py:2(twoSum)

Tôi đã tìm thấy nó rất nhiều thông tin.


1
main()gì Sẽ hữu ích hơn nếu bạn có thể cung cấp một ví dụ mã đơn giản.
not2qubit

15

Tôi thích nó đơn giản (python 3):

from timeit import timeit

timeit(lambda: print("hello"))

Đầu ra là micro giây cho một lần thực hiện:

2.430883963010274

Giải thích : timeit thực thi chức năng ẩn danh 1 triệu lần theo mặc định và kết quả được đưa ra trong vài giây . Do đó, kết quả cho 1 lần thực hiện là cùng một lượng nhưng tính bằng micrô giây .


Đối với các hoạt động chậm, thêm số lần lặp thấp hơn hoặc bạn có thể chờ đợi mãi mãi:

import time

timeit(lambda: time.sleep(1.5), number=1)

Đầu ra luôn tính bằng giây cho tổng số lần lặp:

1.5015795179999714

14

(Chỉ với Ipython) bạn có thể sử dụng % timeit để đo thời gian xử lý trung bình:

def foo():
    print "hello"

và sau đó:

%timeit foo()

kết quả là một cái gì đó như:

10000 loops, best of 3: 27 µs per loop

4
Điều đáng nói là có thể chuyển cờ đến% timeit, ví dụ -n chỉ định số lần lặp lại mã.
raacer

11

Một cách nữa để sử dụng timeit :

from timeit import timeit

def func():
    return 1 + 1

time = timeit(func, number=1)
print(time)

10

trên python3:

from time import sleep, perf_counter as pc
t0 = pc()
sleep(1)
print(pc()-t0)

thanh lịch và ngắn gọn.


Cái này là cái gì? bệnh đa xơ cứng?
KIC

9

Một loại phản ứng siêu muộn, nhưng có lẽ nó phục vụ một mục đích cho một ai đó. Đây là một cách để làm điều đó mà tôi nghĩ là siêu sạch.

import time

def timed(fun, *args):
    s = time.time()
    r = fun(*args)
    print('{} execution took {} seconds.'.format(fun.__name__, time.time()-s))
    return(r)

timed(print, "Hello")

Hãy nhớ rằng "in" là một chức năng trong Python 3 chứ không phải Python 2.7. Tuy nhiên, nó hoạt động với bất kỳ chức năng khác. Chúc mừng!


Làm thế nào tôi có thể in thời gian rất nhỏ? Tôi luôn luôn nhận được 0,0 giây
Rowland Mtetezi

Bạn có thể biến điều này thành một trang trí; Điều này thậm chí còn tốt hơn đối với tôi.
Daniel Moskovich

8

Bạn có thể sử dụng thời gian.

Dưới đây là một ví dụ về cách kiểm tra naive_func có tham số bằng Python REPL:

>>> import timeit                                                                                         

>>> def naive_func(x):                                                                                    
...     a = 0                                                                                             
...     for i in range(a):                                                                                
...         a += i                                                                                        
...     return a                                                                                          

>>> def wrapper(func, *args, **kwargs):                                                                   
...     def wrapper():                                                                                    
...         return func(*args, **kwargs)                                                                  
...     return wrapper                                                                                    

>>> wrapped = wrapper(naive_func, 1_000)                                                                  

>>> timeit.timeit(wrapped, number=1_000_000)                                                              
0.4458435332577161  

Bạn không cần chức năng bao bọc nếu chức năng không có bất kỳ tham số nào.


1
A lambdasẽ gọn gàng hơn:print(timeit.timeit(lambda: naive_func(1_000), number=1_000_000))
Ciro Santilli 病毒 审查 六四 事件

7

Chúng ta cũng có thể chuyển đổi thời gian thành thời gian có thể đọc được của con người.

import time, datetime

start = time.clock()

def num_multi1(max):
    result = 0
    for num in range(0, 1000):
        if (num % 3 == 0 or num % 5 == 0):
            result += num

    print "Sum is %d " % result

num_multi1(1000)

end = time.clock()
value = end - start
timestamp = datetime.datetime.fromtimestamp(value)
print timestamp.strftime('%Y-%m-%d %H:%M:%S')

6

Tôi đã tạo một thư viện cho việc này, nếu bạn muốn đo một chức năng, bạn có thể thực hiện nó như thế này


from pythonbenchmark import compare, measure
import time

a,b,c,d,e = 10,10,10,10,10
something = [a,b,c,d,e]

@measure
def myFunction(something):
    time.sleep(0.4)

@measure
def myOptimizedFunction(something):
    time.sleep(0.2)

myFunction(input)
myOptimizedFunction(input)

https://github.com/Karlheinzniebuhr/pythonbenchmark


6

Để hiểu rõ hơn về mọi chức năng gọi đệ quy, hãy làm:

%load_ext snakeviz
%%snakeviz

Nó chỉ cần lấy 2 dòng mã đó trong một máy tính xách tay Jupyter và nó tạo ra một sơ đồ tương tác tốt đẹp. Ví dụ:

nhập mô tả hình ảnh ở đây

Đây là mã. Một lần nữa, 2 dòng bắt đầu bằng %là dòng mã bổ sung duy nhất cần thiết để sử dụng snakeviz:

# !pip install snakeviz
%load_ext snakeviz
import glob
import hashlib

%%snakeviz

files = glob.glob('*.txt')
def print_files_hashed(files):
    for file in files:
        with open(file) as f:
            print(hashlib.md5(f.read().encode('utf-8')).hexdigest())
print_files_hashed(files)

Dường như có thể chạy snakeviz bên ngoài máy tính xách tay. Thông tin thêm trên trang web snakeviz .


2
import time

def getElapsedTime(startTime, units):
    elapsedInSeconds = time.time() - startTime
    if units == 'sec':
        return elapsedInSeconds
    if units == 'min':
        return elapsedInSeconds/60
    if units == 'hour':
        return elapsedInSeconds/(60*60)

2

Cách tiếp cận dựa trên lớp duy nhất này cung cấp một biểu diễn chuỗi có thể in, làm tròn tùy chỉnh và truy cập thuận tiện vào thời gian đã trôi qua dưới dạng chuỗi hoặc dấu phẩy. Nó được phát triển với Python 3.7.

import datetime
import timeit


class Timer:
    """Measure time used."""
    # Ref: https://stackoverflow.com/a/57931660/

    def __init__(self, round_ndigits: int = 0):
        self._round_ndigits = round_ndigits
        self._start_time = timeit.default_timer()

    def __call__(self) -> float:
        return timeit.default_timer() - self._start_time

    def __str__(self) -> str:
        return str(datetime.timedelta(seconds=round(self(), self._round_ndigits)))

Sử dụng:

# Setup timer
>>> timer = Timer()

# Access as a string
>>> print(f'Time elapsed is {timer}.')
Time elapsed is 0:00:03.
>>> print(f'Time elapsed is {timer}.')
Time elapsed is 0:00:04.

# Access as a float
>>> timer()
6.841332235
>>> timer()
7.970274425

1

Đo thời gian thực hiện của các đoạn mã nhỏ.

Đơn vị thời gian : tính bằng giây như một lần thả nổi

import timeit
t = timeit.Timer('li = list(map(lambda x:x*2,[1,2,3,4,5]))')
t.timeit()
t.repeat()
>[1.2934070999999676, 1.3335035000000062, 1.422568500000125]

Phương thức repeat () là sự tiện lợi để gọi timeit () nhiều lần và trả về danh sách kết quả.

repeat(repeat=3

Với danh sách này, chúng ta có thể có nghĩa là mọi lúc.

Theo mặc định, timeit () tạm thời tắt bộ sưu tập rác trong thời gian. time.Timer () giải quyết vấn đề này.

Ưu điểm:

timeit.Timer () làm cho thời gian độc lập dễ so sánh hơn. Gc có thể là một thành phần quan trọng trong hiệu suất của chức năng được đo. Nếu vậy, gc (bộ thu gom rác) có thể được kích hoạt lại dưới dạng câu lệnh đầu tiên trong chuỗi thiết lập. Ví dụ:

timeit.Timer('li = list(map(lambda x:x*2,[1,2,3,4,5]))',setup='gc.enable()')

Nguồn tài liệu Python !


1

Nếu bạn muốn có thể thực hiện các chức năng thời gian một cách thuận tiện, bạn có thể sử dụng một công cụ trang trí đơn giản:

def timing_decorator(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        original_return_val = func(*args, **kwargs)
        end = time.time()
        print("time elapsed in ", func.__name__, ": ", end - start, sep='')
        return original_return_val

    return wrapper

Bạn có thể sử dụng nó trên một chức năng mà bạn muốn có thời gian như thế này:

@timing_decorator
def function_to_time():
    time.sleep(1)

Sau đó, bất cứ khi nào bạn gọi function_to_time, nó sẽ in mất bao lâu và tên của chức năng được tính thời gian.


1

dựa trên giải pháp bối cảnh được đưa ra bởi https://stackoverflow.com/a/30024601/5095636 , dưới đây là phiên bản miễn phí lambda, vì flake8 cảnh báo về việc sử dụng lambda theo E731 :

from contextlib import contextmanager
from timeit import default_timer

@contextmanager
def elapsed_timer():
    start_time = default_timer()

    class _Timer():
      start = start_time
      end = default_timer()
      duration = end - start

    yield _Timer

    end_time = default_timer()
    _Timer.end = end_time
    _Timer.duration = end_time - start_time

kiểm tra:

from time import sleep

with elapsed_timer() as t:
    print("start:", t.start)
    sleep(1)
    print("end:", t.end)

t.start
t.end
t.duration

1

Cách dễ nhất để tính thời lượng của một hoạt động:

import time

start_time = time.time()
print(time.ctime())

<operations, programs>

print('minutes: ',(time.time() - start_time)/60)

1

Đây là một trang trí gợi ý khá tài liệu và loại đầy đủ tôi sử dụng như một tiện ích chung:

from functools import wraps
from time import perf_counter
from typing import Any, Callable, Optional, TypeVar, cast

F = TypeVar("F", bound=Callable[..., Any])


def timer(prefix: Optional[str] = None, precision: int = 6) -> Callable[[F], F]:
    """Use as a decorator to time the execution of any function.

    Args:
        prefix: String to print before the time taken.
            Default is the name of the function.
        precision: How many decimals to include in the seconds value.

    Examples:
        >>> @timer()
        ... def foo(x):
        ...     return x
        >>> foo(123)
        foo: 0.000...s
        123
        >>> @timer("Time taken: ", 2)
        ... def foo(x):
        ...     return x
        >>> foo(123)
        Time taken: 0.00s
        123

    """
    def decorator(func: F) -> F:
        @wraps(func)
        def wrapper(*args: Any, **kwargs: Any) -> Any:
            nonlocal prefix
            prefix = prefix if prefix is not None else f"{func.__name__}: "
            start = perf_counter()
            result = func(*args, **kwargs)
            end = perf_counter()
            print(f"{prefix}{end - start:.{precision}f}s")
            return result
        return cast(F, wrapper)
    return decorator

Ví dụ sử dụng:

from timer import timer


@timer(precision=9)
def takes_long(x: int) -> bool:
    return x in (i for i in range(x + 1))


print(takes_long(10**8))

Đầu ra:

takes_long: 4.942629056s
True

Các tài liệu có thể được kiểm tra với:

$ python3 -m doctest --verbose -o=ELLIPSIS timer.py

Và gợi ý loại với:

$ mypy timer.py

1
Điều này là siêu mát mẻ, cảm ơn bạn đã chia sẻ. Tôi chưa gặp phải thư viện đánh máy hoặc từ khóa không nhắm mục tiêu - thú vị để tìm những điều mới để tìm hiểu. Tôi đang gặp khó khăn trong đầu của tôi xung quanh này : Callable[[AnyF], AnyF]. Nó có nghĩa là gì?
Daniel

1
@Danny Trên đầu tôi đã xác định bí danh loại AnyFcó nghĩa là Callable[..., Any], vì vậy, AnyFmột hàm có thể lấy bất kỳ số lượng của bất kỳ đối số loại nào và trả về bất cứ điều gì. Vì vậy, Callable[[AnyF], AnyF]sẽ mở rộng đến Callable[[Callable[..., Any]], Callable[..., Any]]. Đây là loại giá trị trả về của timeraka loại đầy đủ decorator. Đây là một hàm lấy bất kỳ loại hàm nào làm đối số duy nhất của nó và trả về bất kỳ loại hàm nào.
ruohola

1
Cảm ơn đã giải thích! Tôi vẫn đang cố gắng hoàn toàn quấn đầu xung quanh các bộ phận trang trí. Điều này đã giúp rất nhiều!
Daniel
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.