Đây thực sự là một vấn đề sâu sắc có một số câu trả lời có phương pháp và thực tế. Tôi giả sử bạn muốn biết điều gì đó về (các) thuật toán trong tay. Nếu bạn muốn biết thuật toán nào hoạt động tốt hơn trên một máy nhất định trên các đầu vào nhất định, hãy tiếp tục và đo thời gian chạy. Nếu bạn muốn so sánh chất lượng của trình biên dịch cho một thuật toán nhất định, hãy tiếp tục và đo thời gian chạy. Để học một cái gì đó về thuật toán, đừng làm điều đó.
Trước tiên tôi xin đưa ra một số lý do tại sao sử dụng thời gian chạy không phải là một ý tưởng tốt.
- Thời gian chạy chung
được đo bằng một ngôn ngữ và một trình biên dịch trên một máy có rất ít ý nghĩa nếu bạn thay đổi bất kỳ thành phần nào. Ngay cả các triển khai khác nhau của cùng một thuật toán có thể thực hiện khác nhau vì bạn kích hoạt một số thao tác trình biên dịch trong trường hợp nhưng không phải trong trường hợp khác.
- Dự đoán
Vì vậy, bạn có một vài thời gian chạy cho một số đầu vào. Điều đó nói gì về thời gian chạy của một số đầu vào khác? Nói chung, không có gì.
- Ý nghĩa
Thông thường, bạn sẽ không điểm chuẩn tất cả các đầu vào (ở một số kích thước), do đó ngay lập tức hạn chế khả năng so sánh các thuật toán của bạn: có thể bộ thử nghiệm của bạn đã kích hoạt trường hợp xấu nhất trong một và trường hợp tốt nhất trong thuật toán khác? Hoặc có thể đầu vào của bạn quá nhỏ để thể hiện hành vi thời gian chạy .
- Đo
thời gian đo thời gian chạy tốt không phải là nhỏ. Có JIT không? Đã có sự tranh chấp, tức là bạn đang đếm thời gian thuật toán thậm chí không chạy? Bạn có thể tái tạo chính xác trạng thái máy tương tự cho một lần chạy khác (của thuật toán khác), đặc biệt là các quy trình và bộ đệm không? Làm thế nào là độ trễ bộ nhớ được xử lý?
Tôi hy vọng những điều này đã thuyết phục bạn rằng thời gian chạy là một biện pháp khủng khiếp để so sánh các thuật toán, và một số phương pháp trừu tượng chung để điều tra thời gian chạy thuật toán là cần thiết.
Về phần thứ hai của câu hỏi. Tại sao chúng ta sử dụng so sánh hoặc các hoạt động cơ bản tương tự?
Khả năng phân tích giả định
Giả sử bạn muốn làm phân tích chính thức, bạn phải có khả năng làm điều đó. Đếm các tuyên bố cá nhân là rất kỹ thuật, đôi khi thậm chí khó khăn; một số người vẫn làm điều đó (ví dụ Knuth). Chỉ đếm một số câu lệnh - những câu thống trị thời gian chạy - là dễ dàng hơn. Vì lý do tương tự, chúng tôi thường "chỉ" điều tra (giới hạn trên) thời gian chạy trường hợp xấu nhất.
Sự thống trị
Các hoạt động được lựa chọn chi phối thời gian chạy. Điều đó không có nghĩa là nó đóng góp nhiều thời gian chạy nhất - các so sánh rõ ràng là không, ví dụ như trong Quicksort khi sắp xếp các số nguyên có kích thước từ. Nhưng chúng được thực thi thường xuyên nhất , vì vậy bằng cách đếm chúng, bạn sẽ đếm tần suất các phần được thực thi nhất của thuật toán được chạy. Do đó, thời gian chạy tiệm cận của bạn tỷ lệ thuận với số lượng các hoạt động cơ bản chi phối. Đây là lý do tại sao chúng tôi thoải mái sử dụng ký hiệu Landau và từ "thời gian chạy" mặc dù chúng tôi chỉ tính so sánh.
Lưu ý rằng có thể hữu ích khi đếm nhiều hơn một thao tác. Ví dụ, một số biến thể Quicksort có nhiều so sánh hơn nhưng ít hoán đổi hơn so với các biến thể khác (trung bình).
Đối với những gì nó có giá trị, sau khi bạn đã thực hiện tất cả các lý thuyết bạn có thể muốn xem lại thời gian chạy để xác minh rằng các dự đoán mà lý thuyết của bạn đưa ra là âm thanh. Nếu chúng không phải, lý thuyết của bạn không hữu ích (trong thực tế) và phải được mở rộng. Phân cấp bộ nhớ là một trong những điều đầu tiên bạn nhận ra là quan trọng nhưng còn thiếu trong các phân tích cơ bản.