Tôi đã sử dụng cProfile để lập hồ sơ mã của mình và nó hoạt động rất tốt. Tôi cũng sử dụng gprof2dot.py để hình dung kết quả (làm cho nó rõ ràng hơn một chút).
Tuy nhiên, cProfile (và hầu hết các trình cấu hình Python khác mà tôi đã thấy cho đến nay) dường như chỉ cấu hình ở cấp độ gọi hàm. Điều này gây ra sự nhầm lẫn khi một số hàm nhất định được gọi từ những nơi khác nhau - tôi không biết liệu lệnh gọi số 1 hay lệnh gọi số 2 đang chiếm phần lớn thời gian. Điều này thậm chí còn tồi tệ hơn khi hàm được đề cập sâu đến sáu cấp, được gọi từ bảy nơi khác.
Làm cách nào để tôi có được một hồ sơ từng dòng?
Thay vì điều này:
function #12, total time: 2.0s
Tôi muốn thấy một cái gì đó như thế này:
function #12 (called from somefile.py:102) 0.5s
function #12 (called from main.py:12) 1.5s
cProfile hiển thị tổng thời gian "chuyển giao" cho cha mẹ, nhưng một lần nữa kết nối này bị mất khi bạn có một loạt các lớp và các cuộc gọi được kết nối với nhau.
Lý tưởng nhất là tôi muốn có một GUI có thể phân tích dữ liệu, sau đó hiển thị cho tôi tệp nguồn của tôi với tổng thời gian cho mỗi dòng. Một cái gì đó như thế này:
main.py:
a = 1 # 0.0s
result = func(a) # 0.4s
c = 1000 # 0.0s
result = func(c) # 5.0s
Sau đó, tôi có thể nhấp vào cuộc gọi "func (c)" thứ hai để xem những gì đang chiếm thời gian trong cuộc gọi đó, tách biệt với cuộc gọi "func (a)".
Điều đó có ý nghĩa? Có thư viện hồ sơ nào thu thập loại thông tin này không? Có công cụ tuyệt vời nào mà tôi đã bỏ qua không?
pstats.print_callers
. Một ví dụ ở đây .