Tin tức và phân tích của tất cả các thiết bị di động

Sử dụng python Timeit để đo thời gian mã

Trong hướng dẫn này, bạn sẽ tìm hiểu cách sử dụng hàm timeit từ mô-đun timeit của Python. Bạn sẽ học cách tính thời gian cho các biểu thức và hàm đơn giản trong Python.

Thời gian mã có thể giúp bạn ước tính thời gian thực thi của một đoạn mã, cũng như xác định các phần mã cần được tối ưu hóa.

Chúng ta sẽ bắt đầu bằng việc tìm hiểu cú pháp hàm timeit của Python. Tiếp theo, chúng ta sẽ xem qua các ví dụ về mã để hiểu cách sử dụng nó cho các khối thời gian và hàm mã trong mô-đun Python. Hãy bắt đầu.

Cách sử dụng chức năng timeit của python

Mô-đun timeit là một phần của thư viện chuẩn Python và bạn có thể nhập nó:

import timeit

Cú pháp sử dụng hàm timeit từ mô-đun timeit được hiển thị bên dưới:

timeit.timeit(stmt, setup, number)

Đây:

  • stmt là một đoạn mã cần đo thời gian thực thi. Bạn có thể chỉ định nó dưới dạng chuỗi python đơn giản hoặc chuỗi nhiều dòng hoặc chuyển tên của người gọi.
  • Như tên cho thấy, thiết lập là một đoạn mã chỉ cần chạy một lần, thường là điều kiện tiên quyết để bắt đầu stmt. Ví dụ: giả sử bạn đang tính thời gian thực hiện để tạo mảng NumPy. Trong trường hợp này, quá trình nhập numpy là mã thiết lập và bản dựng thực tế là hướng dẫn được tính thời gian.
  • Số tham số chỉ định số lần chạy stmt. Giá trị số mặc định là 1 triệu (1000000), nhưng bạn cũng có thể đặt tham số này thành bất kỳ giá trị nào khác mà bạn chọn.

Bây giờ chúng ta đã biết cú pháp của hàm timeit(), hãy bắt đầu viết mã một số ví dụ.

Thời gian Biểu thức python đơn giản

Trong phần này, chúng tôi sẽ cố gắng đo thời gian thực hiện các biểu thức Python đơn giản bằng timeit.

Chạy REPL Python và chạy các ví dụ mã sau. Ở đây chúng tôi tính toán thời gian thực hiện lũy thừa và chia sàn cho các lần chạy 10000 và 100000.

Lưu ý rằng chúng ta chuyển lệnh định thời gian dưới dạng chuỗi python và sử dụng dấu chấm phẩy để phân tách các biểu thức khác nhau trong lệnh.

>>> import timeit
>>> timeit.timeit('3**4;3//4',number=10000)
0.0004020999999738706

>>> timeit.timeit('3**4;3//4',number=100000)
0.0013780000000451764

Chạy python timeit trên dòng lệnh

Bạn cũng có thể sử dụng timeit trên dòng lệnh. Đây là cách tương đương với việc gọi timeit từ dòng lệnh:

$ python-m timeit -n [number] -s [setup] [stmt]
  • python -m timeit có nghĩa là chúng ta đang chạy timeit làm mô-đun chính.
  • n là một tùy chọn dòng lệnh chỉ định số lần mã sẽ được chạy. Điều này tương đương với đối số number trong lệnh gọi timeit().
  • Bạn có thể sử dụng tùy chọn -s để xác định mã cài đặt.

Ở đây chúng tôi viết lại ví dụ trước bằng cách sử dụng dòng lệnh tương đương:

$ python -m timeit -n 100000 '3**4;3//4'
100000 loops, best of 5: 35.8 nsec per loop

Trong ví dụ này, chúng tôi tính toán thời gian thực hiện của hàm len() tích hợp. Việc khởi tạo chuỗi là mã thiết lập được truyền bằng tùy chọn s.

$ python -m timeit -n 100000 -s "string_1 = 'coding'" 'len(string_1)'
100000 loops, best of 5: 239 nsec per loop

Lưu ý rằng ở đầu ra, chúng ta có được thời gian thực hiện tốt nhất 5 dạng sóng. Nó có nghĩa là gì? Khi bạn chạy timeit trên dòng lệnh, tùy chọn lặp lại r được đặt thành giá trị mặc định 5. Điều này có nghĩa là việc thực thi stmt với số lần đã chỉ định sẽ được lặp lại năm lần và trả về thời gian thực hiện tốt nhất.

Phân tích các phương pháp đảo ngược chuỗi bằng timeit

Khi làm việc với chuỗi python, bạn có thể muốn đảo ngược chúng. Hai cách tiếp cận phổ biến nhất để đảo ngược chuỗi như sau:

  • Sử dụng cắt chuỗi
  • Sử dụng đảo ngược() và tham gia().

Đảo ngược chuỗi python bằng cách cắt chuỗi

Chúng ta hãy xem cách cắt chuỗi hoạt động và cách sử dụng nó để đảo ngược chuỗi trong Python. Sử dụng cú pháp một số chuỗi[start:stop] trả về một lát của chuỗi bắt đầu ở đầu chỉ mục và kết thúc ở chỉ mục dừng1. Hãy lấy một ví dụ.

Hãy xem xét chuỗi “Python” sau đây. Dây chuyền có chiều dài 6và danh sách các chỉ mục là 0, 1, 2 xuống 5.

>>> string_1 = 'Python'

Khi bạn chỉ định cả giá trị bắt đầu và giá trị kết thúc, bạn sẽ nhận được một đoạn chuỗi kéo dài từ đầu đến cuối-1. Vì vậy, chuỗi_1[1:4] trả về ‘y’.

>>> string_1 = 'Python'
>>> string_1[1:4]
'yth'

Nếu không có giá trị hạt giống nào được chỉ định, giá trị hạt giống mặc định bằng 0 sẽ được sử dụng và lát cắt bắt đầu ở chỉ số 0 và kéo dài đến cuối – 1.

Ở đây giá trị dừng là 3vì vậy lát cắt bắt đầu ở chỉ mục 0 và đi đến chỉ mục 2.

>>> string_1[:3]
'Pyt'

Nếu bạn không bao gồm chỉ mục dừng, bạn sẽ thấy lát cắt bắt đầu ở chỉ mục bắt đầu (1) và kéo dài đến cuối chuỗi.

>>> string_1[1:]
'ython'

Bỏ qua cả giá trị bắt đầu và kết thúc sẽ trả về một lát của toàn bộ chuỗi.

>>> string_1[::]
'Python'

Hãy tạo một lát cắt có giá trị bước. Đặt giá trị bắt đầu, dừng và bước tương ứng 1, 5 Và 2. Chúng tôi nhận được một lát chuỗi bắt đầu bằng 1 mở rộng đến 4 (không bao gồm điểm cuối 5) chứa mỗi ký tự thứ hai.

>>> string_1[1:5:2]
'yh'

Khi bạn sử dụng bước phủ định, bạn có thể nhận được một lát cắt bắt đầu ở cuối chuỗi. Với bước được đặt thành -2chuỗi_1[5:2:-2] đưa ra đoạn mã sau:

>>> string_1[5:2:-2]
'nh'

Để có được bản sao đảo ngược của chuỗi, chúng tôi bỏ qua giá trị bắt đầu và kết thúc và đặt bước thành -1như được hiển thị:

>>> string_1[::-1]
'nohtyP'

Tóm lại: chuỗi[::-1] trả về một bản sao đảo ngược của chuỗi.

Đảo ngược chuỗi bằng cách sử dụng các hàm và phương thức chuỗi tích hợp

Hàm đảo ngược() tích hợp của Python sẽ trả về một trình vòng lặp ngược trên các phần tử chuỗi.

>>> string_1 = 'Python'
>>> reversed(string_1)
<reversed object at 0x00BEAF70>

Vì vậy, bạn có thể đi qua vòng lặp ngược bằng vòng lặp for:

for char in reversed(string_1):
    print(char)

Và truy cập các phần tử của chuỗi theo thứ tự ngược lại.

# Output
n
o
h
t
y
P

Sau đó, bạn có thể gọi phương thức join() trong trình vòng lặp ngược với cú pháp: .join(reversed(some-string)).

Đoạn mã bên dưới hiển thị một số ví dụ trong đó dấu phân cách lần lượt là dấu gạch nối và dấu cách.

>>> '-'.join(reversed(string1))
'n-o-h-t-y-P'
>>> ' '.join(reversed(string1))
'n o h t y P'

Chúng tôi không muốn có bất kỳ dấu phân cách nào ở đây; vì vậy hãy đặt dấu phân cách thành một chuỗi trống để có được bản sao đảo ngược của chuỗi:

>>> ''.join(reversed(string1))
'nohtyP'

Việc sử dụng .join(reversed(some-string)) trả về một bản sao bị đảo ngược của chuỗi.

So sánh thời gian thực hiện với timeit

Cho đến nay, chúng ta đã thấy hai cách tiếp cận để đảo ngược chuỗi Python. Nhưng cái nào nhanh hơn? Hãy cùng tìm hiểu.

Trong ví dụ trước, nơi chúng tôi tính thời gian cho các biểu thức Python đơn giản, chúng tôi không có bất kỳ mã thiết lập nào. Ở đây chúng tôi đảo ngược chuỗi python. Mặc dù thao tác đảo ngược chuỗi được thực hiện nhiều lần theo số lượng được chỉ định, mã thiết lập là khởi tạo chuỗi sẽ chỉ được thực thi một lần.

>>> import timeit
>>> timeit.timeit(stmt="string_1[::-1]", setup = "string_1 = 'Python'", number = 100000)
0.04951830000001678
>>> timeit.timeit(stmt = "''.join(reversed(string_1))", setup = "string_1 = 'Python'", number = 100000)
0.12858760000000302

Với cùng số lần đảo ngược cho một chuỗi nhất định, cách tiếp cận chuỗi phân tách nhanh hơn so với join() và Reverse().

Đồng bộ hóa hàm Python bằng timeit

Trong phần này, chúng ta sẽ tìm hiểu cách tính thời gian cho các hàm Python bằng hàm timeit. Cho một danh sách các chuỗi, hàm hasDigit sau đây trả về danh sách các chuỗi có ít nhất một chữ số.

def hasDigit(somelist):
     str_with_digit = []
     for string in somelist:
         check_char = [char.isdigit() for char in string]
         if any(check_char):
            str_with_digit.append(string)
     return str_with_digit

Bây giờ chúng tôi muốn đo thời gian thực hiện của hàm hasDigit() này bằng cách sử dụng timeit.

Đầu tiên, hãy xác định lệnh cần tính thời gian (stmt). Đây là lệnh gọi hasDigit() với danh sách các chuỗi làm đối số. Tiếp theo, hãy xác định mã cài đặt. Bạn có thể đoán mã thiết lập sẽ là gì không?

Để hàm được gọi thành công, mã cài đặt phải chứa các phần tử sau:

  • Định nghĩa của hasDigit()
  • Khởi tạo danh sách đối số chuỗi

Hãy xác định mã cài đặt trong chuỗi cài đặt như dưới đây:

setup = """
def hasDigit(somelist):
    str_with_digit = []
    for string in somelist:
      check_char = [char.isdigit() for char in string]
      if any(check_char):
        str_with_digit.append(string)
    return str_with_digit
thislist=['puffin3','7frost','blue']
     """

Sau đó, chúng ta có thể sử dụng hàm timeit và nhận thời gian thực hiện của hasDigit() trong 100000 lượt.

import timeit
timeit.timeit('hasDigit(thislist)',setup=setup,number=100000)
# Output
0.2810094920000097

Ứng dụng

Bạn đã học cách sử dụng hàm timeit của Python để chỉ định thời gian trong biểu thức, hàm và các lệnh gọi khác. Điều này có thể giúp bạn đánh giá mã của mình, so sánh thời gian thực thi của các cách triển khai khác nhau của cùng một chức năng, v.v.

Chúng ta hãy xem những gì chúng ta đã học được trong hướng dẫn này. Bạn có thể sử dụng hàm timeit() với cú pháp timeit.timeit(stmt=…,setup=…,number=…). Ngoài ra, bạn có thể chạy timeit trên dòng lệnh để tính thời gian cho các đoạn mã ngắn.

Trong bước tiếp theo, bạn có thể khám phá cách sử dụng các gói lược tả Python khác, chẳng hạn như line-profiler và memprofiler, để lập cấu hình mã của bạn theo thời gian và bộ nhớ tương ứng.

Sau đó tìm hiểu cách tính chênh lệch thời gian trong python.