Hướng dẫn how do you test the speed of a python code? - làm thế nào để bạn kiểm tra tốc độ của mã python?

Rất nhiều bài viết trong loạt bài này tận dụng một tính năng của Python cho phép chúng tôi kiểm tra hiệu suất mã của chúng tôi và cuối cùng tôi muốn đi xung quanh để giải thích cách nó hoạt động và cách sử dụng nó.

Trong bài viết này, tôi bao gồm ba kỹ thuật chính: Brute Force, timeit

[(a, b) for a in (1, 3, 5) for b in (2, 4, 6)]
0. Cá nhân, tôi kiểm tra hiệu suất mã của mình bằng timeit vì tôi thấy nó dễ hiểu, nhưng bạn có thể thấy các công cụ định hình khác nhau hữu ích. Cuối cùng, tôi sẽ yêu cầu bạn thể hiện các kỹ năng mới của bạn với một thử thách.

Mục lục

Giới thiệu vấn đề

Để bắt đầu nói về cách kiểm tra hiệu suất mã Python, chúng ta cần xác định nó. Ở cấp độ cao, kiểm tra hiệu suất là bất cứ điều gì xác minh tốc độ, độ tin cậy, khả năng mở rộng và/hoặc tính ổn định của phần mềm. Đối với mục đích của chúng tôi, chúng tôi sẽ nhìn vào tốc độ. Cụ thể, chúng tôi sẽ xem xét các cách khác nhau để so sánh tốc độ của hai chương trình bằng thời gian thực hiện tương đối của họ.

Khi nói đến phần mềm thử nghiệm hiệu suất, quá trình này luôn luôn dễ dàng hoặc rõ ràng. Đặc biệt, có rất nhiều cạm bẫy. Ví dụ, các bài kiểm tra hiệu suất có thể bị ảnh hưởng bởi tất cả các loại yếu tố như quy trình nền (nghĩa là Spotify, Eclipse, GitHub Desktop, v.v.).

Ngoài ra, các bài kiểm tra hiệu suất cũng không phải là cách viết theo cách khá khác biệt về sự khác biệt trong việc thực hiện. Ví dụ: tôi có thể có hai đoạn mã có cùng hành vi ngoại trừ một đoạn yêu cầu một thư viện được nhập. Khi tôi chạy bài kiểm tra của mình, tôi không muốn nhập khẩu ảnh hưởng đến kết quả kiểm tra. Kết quả là, tôi nên viết các bài kiểm tra của mình sao cho tôi không bắt đầu thời gian cho đến khi thư viện được nhập.

Trên hết, điều quan trọng là phải tính đến các loại kịch bản khác nhau khi kiểm tra hiệu suất. Chẳng hạn, nếu chúng ta có hai đoạn trích tương tự, người ta có thể có hiệu suất tốt hơn cho các bộ dữ liệu lớn hơn. Nó rất quan trọng để kiểm tra một loạt các bộ dữ liệu vì lý do đó.

Ở bất cứ giá nào, mục tiêu của bài viết này là xem xét một vài cách khác nhau mà chúng ta có thể thực hiện mã kiểm tra trong Python. Nào cùng đào vào bên trong!

Các giải pháp

Như mọi khi, tôi thích chia sẻ một vài cách để hoàn thành nhiệm vụ của chúng tôi. Tất nhiên, nếu bạn đã theo dõi trong loạt bài này, bạn sẽ biết rằng tôi thích sử dụng thư viện timeit để kiểm tra các đoạn trích. May mắn thay, có nhiều lựa chọn hơn nếu timeit không phải là dành cho bạn.

Kiểm tra hiệu suất của vũ lực

Nếu bạn không bao giờ thực hiện bất kỳ thử nghiệm hiệu suất nào trước đây, có lẽ bạn có một ý chính về cách bắt đầu. Thông thường, chúng tôi muốn có dấu thời gian trước và sau khi chúng tôi chạy đoạn mã của chúng tôi. Sau đó, chúng ta có thể tính toán sự khác biệt giữa những thời điểm đó và sử dụng kết quả trong việc so sánh với các đoạn trích khác.

Để làm điều này trong Python, chúng ta có thể tận dụng thư viện

[(a, b) for a in (1, 3, 5) for b in (2, 4, 6)]
4:

import datetime
start_time = datetime.datetime.now()
# insert code snippet here
end_time = datetime.datetime.now()
print(end_time - start_time)

Tất nhiên, giải pháp này để lại rất nhiều mong muốn. Ví dụ, nó chỉ cung cấp cho chúng ta một điểm dữ liệu duy nhất. Lý tưởng nhất, chúng tôi muốn chạy điều này một vài lần để thu thập trung bình hoặc ít nhất là giới hạn thấp hơn, nhưng điều này có thể làm trong một nhúm.

Kiểm tra hiệu suất bằng thư viện thời gian

Nếu bạn thích có tất cả các thùng rác dấu thời gian này được trừu tượng hóa với việc bổ sung một vài đặc quyền, hãy xem thư viện timeit. Với thư viện timeit, về cơ bản có hai cách chính để kiểm tra mã: dòng lệnh hoặc nội tuyến. Đối với mục đích của chúng tôi, chúng tôi sẽ xem xét phiên bản nội tuyến vì đó là những gì tôi sử dụng cho tất cả các thử nghiệm của mình.

Để kiểm tra mã bằng thư viện timeit, bạn sẽ cần gọi hàm timeit hoặc hàm

[(a, b) for a in (1, 3, 5) for b in (2, 4, 6)]
9. Một trong hai là tốt, nhưng chức năng
[(a, b) for a in (1, 3, 5) for b in (2, 4, 6)]
9 cho phép kiểm soát nhiều hơn một chút.

Ví dụ, chúng tôi sẽ kiểm tra đoạn mã sau từ một bài viết trước về danh sách toàn diện:

[(a, b) for a in (1, 3, 5) for b in (2, 4, 6)]

Trong đoạn trích này, chúng tôi đã tạo ra một danh sách các cặp từ hai bộ dữ liệu. Để kiểm tra nó, chúng tôi có thể sử dụng chức năng timeit:

import timeit
timeit.timeit("[(a, b) for a in (1, 3, 5) for b in (2, 4, 6)]")

Nếu được thực hiện chính xác, điều này sẽ chạy đoạn trích một triệu lần và kết quả là trả lại thời gian thực hiện trung bình. Tất nhiên, bạn có thể chào đón để thay đổi số lần lặp bằng cách sử dụng đối số từ khóa

import timeit
timeit.timeit("[(a, b) for a in (1, 3, 5) for b in (2, 4, 6)]")
2:

import timeit
timeit.timeit("[(a, b) for a in (1, 3, 5) for b in (2, 4, 6)]", number=1000)

Đương nhiên, chúng ta có thể thực hiện bài kiểm tra này một bước nữa bằng cách chạy nó nhiều lần bằng cách sử dụng hàm lặp lại:

import timeit
timeit.repeat("[(a, b) for a in (1, 3, 5) for b in (2, 4, 6)]")

Thay vì trả về thời gian thực hiện, chức năng này trả về một danh sách thời gian thực hiện. Trong trường hợp này, danh sách sẽ chứa ba thời gian thực hiện riêng biệt. Tất nhiên, chúng tôi không cần tất cả những lần đó. Thay vào đó, chúng ta có thể trả về thời gian thực hiện nhỏ nhất, vì vậy chúng ta có thể có ý tưởng về giới hạn dưới của đoạn trích:

import timeit
min(timeit.repeat("[(a, b) for a in (1, 3, 5) for b in (2, 4, 6)]"))

Nếu bạn đã ở xung quanh một chút, bạn có thể đã thấy cú pháp chính xác này trong các bài kiểm tra hiệu suất của tôi trong các bài viết hoặc video khác. Tất nhiên, tôi đi xa hơn và tăng số lần lặp lại, nhưng nó có thể quá mức cần thiết. Trong mọi trường hợp, đây là một cách tuyệt vời để kiểm tra hiệu suất Python.

Kiểm tra hiệu suất bằng thư viện CPROFILE

Ngoài timeit và lực lượng vũ phu hoàn toàn, bạn luôn có thể tận dụng các công cụ định hình khác như cprofile. Giống như timeit, chúng ta có thể tận dụng

[(a, b) for a in (1, 3, 5) for b in (2, 4, 6)]
0 để có được số liệu thống kê thời gian chạy từ một phần mã. Tất nhiên, cprofile khá chi tiết hơn một chút. Ví dụ: chúng ta có thể chạy cùng một danh sách hiểu từ phía trên như sau:
Hướng dẫn how do you test the speed of a python code? - làm thế nào để bạn kiểm tra tốc độ của mã python?
. Like timeit, we can leverage
[(a, b) for a in (1, 3, 5) for b in (2, 4, 6)]
0 to get runtime statistics from a section of code. Of course, cProfile is quite a bit more detailed. For example, we can run the same list comprehension from above as follows:

import cProfile
cProfile.run("[(a, b) for a in (1, 3, 5) for b in (2, 4, 6)]")

Kết quả là, bạn nhận được một báo cáo tốt đẹp trông như thế này:

4 function calls in 0.000 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    0.000    0.000 :1()
        1    0.000    0.000    0.000    0.000 :1()
        1    0.000    0.000    0.000    0.000 {built-in method builtins.exec}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

Ở đây, chúng tôi nhận được một bảng đẹp bao gồm rất nhiều thông tin hữu ích. Cụ thể, mỗi hàng chỉ ra một hàm được thực thi và mỗi cột phá vỡ một phân đoạn thời gian chạy khác nhau. Ví dụ: hàm

import timeit
timeit.timeit("[(a, b) for a in (1, 3, 5) for b in (2, 4, 6)]")
6 được gọi một lần (
import timeit
timeit.timeit("[(a, b) for a in (1, 3, 5) for b in (2, 4, 6)]")
7) và mất 0,000 giây (
import timeit
timeit.timeit("[(a, b) for a in (1, 3, 5) for b in (2, 4, 6)]")
8) không bao gồm các cuộc gọi đến các subfunce. Để hiểu mọi thứ khác trong bảng này, hãy xem sự cố sau của tất cả sáu cột:

  • NCALLS: Số lần chức năng cụ thể được gọi: the number of times that particular function was called
    • Số này thực sự có thể được viết dưới dạng phân số (ví dụ:
      import timeit
      timeit.timeit("[(a, b) for a in (1, 3, 5) for b in (2, 4, 6)]")
      9) trong đó giá trị đầu tiên là số lượng cuộc gọi tổng số và giá trị thứ hai là số lượng các cuộc gọi nguyên thủy (không đệ quy).
  • Tottime: Tổng thời gian chức năng dành cho việc thực hiện không bao gồm các cuộc gọi đến: the total amount of time the function spent executing not including calls to subfunctions
  • Percall (đầu tiên): Tỷ lệ của NCALLS (tức là lượng thời gian trung bình dành cho chức năng này không bao gồm các tiểu thư) (first): the ratio of tottime to ncalls (i.e. the average amount of time spent in this function excluding subfunctions)
  • Cumtime: Tổng số thời gian mà hàm đã sử dụng thực thi bao gồm các cuộc gọi đến: the total amount of time the function spent executing including calls to subfunctions
  • Percall (thứ hai): tỷ lệ của cumtime so với các cuộc gọi nguyên thủy (nghĩa là lượng thời gian trung bình dành cho chức năng này) (second): the ratio of cumtime to primitive calls (i.e. the average amount of time spent in this function)
  • Tên tệp: Lineno (chức năng): Tên tệp, số dòng và chức năng được đề cập: the filename, line number, and function in question

Như bạn có thể thấy,

[(a, b) for a in (1, 3, 5) for b in (2, 4, 6)]
0 giúp bạn nhìn trộm các hoạt động nội bộ của đoạn mã. Tất nhiên, bạn không nhận được thời gian hạt mịn, vì vậy điều này hoạt động tốt hơn như là một lời khen cho timeit thay vì thay thế. Điều đó nói rằng, tôi nghĩ rằng
[(a, b) for a in (1, 3, 5) for b in (2, 4, 6)]
0 sẽ là tuyệt vời cho việc hồ sơ các kịch bản lớn. Bằng cách đó, bạn có thể xác định chức năng nào cần tối ưu hóa.

Kiểm tra hiệu suất với các thư viện bên ngoài

Mặc dù Python cung cấp nhiều cách để đánh giá mã của riêng bạn, nhưng cũng có những thư viện khác mà chúng tôi cũng có thể tận dụng. Ví dụ:

Cá nhân, tôi không bao giờ sử dụng bất kỳ công cụ nào trong số này, nhưng tôi cảm thấy tôi nên chia sẻ chúng vì sự hoàn chỉnh. Hãy theo dõi các liên kết để tìm hiểu thêm.

Thách đấu

Tại thời điểm này, tôi đã chia sẻ một số số liệu hiệu suất cho từng giải pháp ở trên, nhưng điều đó không thực sự có ý nghĩa trong bối cảnh này. Thay vào đó, nó thời gian để nhảy thẳng vào thử thách!

Chọn một trong những bài viết trong loạt bài này và chạy các số liệu hiệu suất của riêng bạn trên mỗi giải pháp. Vì tôi thường chạy timeit, có lẽ bạn có thể thử sử dụng một trong các công cụ khác từ bài viết này. Ví dụ: hãy thử chạy CPROFILE trên tất cả các giải pháp định dạng chuỗi.

Khi bạn hoàn thành, hãy chia sẻ kết quả tốt nhất trong các ý kiến. Tôi quan tâm để xem những gì bạn học được! Trong khi bạn ở đó, hãy kiểm tra công việc của tôi. Tôi rất thích biết nếu có những giải pháp khác mà tôi đã thiếu.

Một chút tóm tắt

Như mọi khi, tôi thích kết thúc mọi thứ với một danh sách các tùy chọn. Hãy nhớ rằng mỗi giải pháp tận dụng một đoạn mã ví dụ. Trong trường hợp này, tôi đã chọn một danh sách hiểu, nhưng bạn có thể sử dụng bất kỳ đoạn trích nào:

# Brute force solution
import datetime
start_time = datetime.datetime.now()
[(a, b) for a in (1, 3, 5) for b in (2, 4, 6)] # example snippet
end_time = datetime.datetime.now()
print(end_time - start_time)

# timeit solution
import timeit
min(timeit.repeat("[(a, b) for a in (1, 3, 5) for b in (2, 4, 6)]"))

# cProfile solution
import cProfile
cProfile.run("[(a, b) for a in (1, 3, 5) for b in (2, 4, 6)]")

Chà, đó là tất cả những gì tôi đã có! Nếu bạn có bất kỳ công cụ hiệu suất nào của riêng bạn để thêm vào danh sách, vui lòng chia sẻ chúng trong các bình luận.

Trong khi đó, tôi có rất nhiều bài viết của Python mà bạn có thể quan tâm:

  • Cách sắp xếp một danh sách các chuỗi trong Python
  • Cách nhận mục cuối cùng của danh sách trong Python
  • Cách kiểm tra xem một tệp có tồn tại trong Python không

Nếu bạn thích phương tiện trực quan, tôi có một kênh YouTube hiện đang tập trung vào việc giải thích nội dung từ loạt bài này. Đi đến đó và ném cho tôi một đăng ký để giúp tôi xây dựng kênh của mình.

Hướng dẫn how do you test the speed of a python code? - làm thế nào để bạn kiểm tra tốc độ của mã python?
which is currently focused on explaining content from this series. Head on over there and throw me a subscribe to help me build up my channel.

Ngoài ra, cảm thấy tận dụng một số tài nguyên liên quan sau đây được cung cấp bởi Amazon:

Cuối cùng, bạn luôn có thể nhận được nội dung mã hóa Renegade mới nhất được gửi đến hộp thư đến của bạn thông qua danh sách email. Nếu bạn muốn đi thêm một dặm, hãy ném cho tôi một vài đô la vào Patreon. Bạn đã giành được sự hối tiếc của nó!

Hướng dẫn how do you test the speed of a python code? - làm thế nào để bạn kiểm tra tốc độ của mã python?
. You won’t regret it!

Ở bất cứ giá nào, cho đến lần sau!

Làm thế nào để bạn kiểm tra mã của bạn là Python nhanh như thế nào?

Sử dụng các chức năng dưới đây để đo thời gian thực hiện của chương trình trong Python:..
thời gian. Time (): Đo tổng thời gian trôi qua để thực thi mã tính bằng giây ..
thời gian. ....
%Timeit và %% Timeit: Lệnh để có thời gian thực hiện của một dòng mã và nhiều dòng mã ..
datetime..

Làm cách nào để kiểm tra kịch bản Python?

1 Cách viết và kiểm tra chương trình Python..
Viết một chương trình Python để nói Hello Hello, thế giới!
Xử lý các đối số dòng lệnh bằng argparse ..
Chạy các bài kiểm tra cho mã với pytest ..
Tìm hiểu về $ PATH ..
Sử dụng các công cụ như Yapf và Black để định dạng mã ..
Sử dụng các công cụ như Flake8 và Pylint để tìm sự cố trong mã ..

Python có thể được biên dịch cho tốc độ không?

Nó không thực hiện biên dịch trước thời gian vì sự năng động vốn có của Python, không thể biên dịch Python thành một nhị phân độc lập và sử dụng lại nó.Pypy là một trình thông dịch thời gian chạy nhanh hơn một ngôn ngữ được giải thích đầy đủ, nhưng nó chậm hơn một ngôn ngữ được biên dịch đầy đủ như C.it's impossible to compile Python into a standalone binary and reuse it. PyPy is a runtime interpreter that is faster than a fully interpreted language, but it's slower than a fully compiled language such as C.

Mô -đun nào giúp kiểm tra hiệu suất của mã Python?

Python đi kèm với mô -đun CPROFILE để giúp đánh giá hiệu suất.Nó không chỉ cung cấp tổng thời gian chạy, nó còn nhiều lần mỗi chức năng riêng biệt.cProfile module to help evaluate performance. It not only gives the total running time, it also times each function separately.