Tại sao các thanh tiến độ rất không chính xác?
Thoạt đầu, dường như việc tạo ra một ước tính chính xác về thời gian nên khá dễ dàng. Rốt cuộc, thuật toán tạo ra thanh tiến trình biết tất cả các nhiệm vụ cần thực hiện trước thời gian, đúng?
Đối với hầu hết các phần, đúng là thuật toán nguồn thực sự biết những gì nó cần làm trước thời hạn. Tuy nhiên, việc xác định thời gian cần thiết để thực hiện từng bước là một việc rất khó, nếu không muốn nói là hầu như không thể.
Tất cả các nhiệm vụ không được tạo ra bằng nhau
Cách đơn giản nhất để thực hiện một thanh tiến trình là sử dụng biểu diễn đồ họa của bộ đếm tác vụ. Trường hợp phần trăm hoàn thành được tính đơn giản là Nhiệm vụ đã hoàn thành / Tổng số nhiệm vụ. Trong khi điều này có ý nghĩa logic trên suy nghĩ đầu tiên, điều quan trọng cần nhớ là (rõ ràng) một số nhiệm vụ mất nhiều thời gian hơn để hoàn thành.
Hãy xem xét các tác vụ sau được thực hiện bởi trình cài đặt:
- Tạo cấu trúc thư mục.
- Giải nén và sao chép các tập tin trị giá 1 GB.
- Tạo các mục đăng ký.
- Tạo các mục menu bắt đầu.
Trong ví dụ này, các bước 1, 3 và 4 sẽ hoàn thành rất nhanh trong khi bước 2 sẽ mất một chút thời gian. Vì vậy, một thanh tiến trình làm việc với số đếm đơn giản sẽ tăng lên 25% rất nhanh, dừng lại một chút trong khi bước 2 đang hoạt động, và sau đó nhảy lên 100% gần như ngay lập tức.
Kiểu thực hiện này thực sự khá phổ biến trong các thanh tiến trình bởi vì, như đã nêu ở trên, nó rất dễ thực hiện. Tuy nhiên, như bạn có thể thấy, nó có thể chịu các nhiệm vụ không tương xứng làm lệch hướng thực tế phần trăm tiến độ vì nó liên quan đến thời gian còn lại.
Để khắc phục điều này, một số thanh tiến trình có thể sử dụng các triển khai trong đó các bước được tính trọng số. Xem xét các bước ở trên nơi trọng số tương đối được chỉ định cho mỗi bước:
- Tạo cấu trúc thư mục. [Trọng lượng = 1]
- Giải nén và sao chép các tập tin trị giá 1 GB. [Trọng lượng = 7]
- Tạo các mục đăng ký. [Trọng lượng = 1]
- Tạo các mục menu bắt đầu. [Trọng lượng = 1]
Sử dụng phương pháp này, thanh tiến trình sẽ di chuyển theo gia số 10% (vì tổng trọng lượng là 10) với các bước 1, 3 và 4 di chuyển thanh 10% khi hoàn thành và bước 2 di chuyển 70%. Mặc dù chắc chắn không hoàn hảo, các phương pháp như thế này là một cách đơn giản để thêm độ chính xác hơn một chút vào phần trăm thanh tiến trình.
Kết quả trong quá khứ Không đảm bảo hiệu suất trong tương lai
Hãy xem xét một ví dụ đơn giản về tôi yêu cầu bạn đếm đến 50 trong khi tôi sử dụng đồng hồ bấm giờ để hẹn giờ với bạn. Giả sử bạn đếm đến 25 trong 10 giây. Sẽ là hợp lý khi giả sử bạn sẽ đếm các số còn lại trong 10 giây nữa, do đó, thanh theo dõi tiến trình này sẽ hiển thị 50% hoàn thành với 10 giây còn lại.
Tuy nhiên, khi số đếm của bạn đạt 25, tôi bắt đầu ném bóng tennis vào bạn. Có khả năng, điều này sẽ phá vỡ nhịp điệu của bạn vì sự tập trung của bạn đã chuyển từ việc đếm số nghiêm ngặt sang né tránh những quả bóng ném theo cách của bạn. Giả sử bạn có thể tiếp tục đếm, tốc độ của bạn chắc chắn đã chậm lại một chút. Vì vậy, bây giờ thanh tiến trình vẫn đang di chuyển, nhưng với tốc độ chậm hơn nhiều với thời gian ước tính còn lại hoặc đứng yên hoặc thực sự leo cao hơn.
Đối với một ví dụ thực tế hơn về điều này, hãy xem xét tải xuống tệp. Bạn hiện đang tải xuống tệp 100 MB với tốc độ 1 MB / s. Điều này rất dễ dàng để xác định thời gian ước tính hoàn thành. Nhưng 75% cách đó, một số lần tắc nghẽn mạng và tốc độ tải xuống của bạn giảm xuống 500 KB / s.
Tùy thuộc vào cách trình duyệt tính toán thời gian còn lại, ETA của bạn có thể ngay lập tức chuyển từ 25 giây xuống 50 giây (chỉ sử dụng trạng thái hiện tại: Kích thước còn lại / Tốc độ tải xuống) hoặc, rất có thể, trình duyệt sử dụng thuật toán trung bình cuộn sẽ điều chỉnh các dao động về tốc độ truyền mà không hiển thị các bước nhảy ấn tượng cho người dùng.
Một ví dụ về thuật toán cuộn liên quan đến việc tải xuống một tệp có thể hoạt động giống như thế này:
- Tốc độ truyền trong 60 giây trước được ghi nhớ bằng giá trị mới nhất thay thế giá trị cũ nhất (ví dụ: giá trị thứ 61 thay thế giá trị đầu tiên).
- Tốc độ truyền hiệu quả cho mục đích tính toán là trung bình của các phép đo này.
- Thời gian còn lại được tính như sau: Kích thước còn lại / Tốc độ tải xuống hiệu quả
Vì vậy, sử dụng kịch bản của chúng tôi ở trên (để đơn giản, chúng tôi sẽ sử dụng 1 MB = 1.000 KB):
- Sau 75 giây tải xuống, 60 giá trị được ghi nhớ của chúng tôi sẽ là 1.000 KB. Tốc độ truyền hiệu quả là 1.000 KB (60.000 KB / 60) mang lại thời gian còn lại là 25 giây (25.000 KB / 1.000 KB).
- Ở mức 76 giây (khi tốc độ truyền giảm xuống 500 KB), tốc độ tải xuống hiệu quả trở thành ~ 992 KB (59.500 KB / 60) mang lại thời gian còn lại là ~ 24,7 giây (24.500 KB / 992 KB).
- Ở 77 giây: Tốc độ hiệu quả = ~ 983 KB (59.000 KB / 60) thời gian mang lại còn lại là ~ 24,4 giây (24.000 KB / 983 KB).
- Ở 78 giây: Tốc độ hiệu quả = 975 KB (58.500 KB / 60) thời gian cho năng suất còn lại là ~ 24,1 giây (23.500 KB / 975 KB).
Bạn có thể thấy mô hình nổi lên ở đây khi tốc độ tải xuống chậm được tích hợp vào mức trung bình được sử dụng để ước tính thời gian còn lại. Theo phương pháp này, nếu quá trình nhúng chỉ kéo dài trong 10 giây và sau đó trở về 1 MB / s, người dùng sẽ không nhận thấy sự khác biệt (tiết kiệm cho một gian hàng rất nhỏ trong thời gian đếm ngược ước tính).
Truy cập vào các đồng thau - đây đơn giản là phương pháp để chuyển tiếp thông tin đến người dùng cuối vì nguyên nhân cơ bản thực tế
Bạn không thể xác định chính xác một cái gì đó không đặc biệt
Cuối cùng, sự thiếu chính xác của thanh tiến trình làm cho thực tế rằng nó đang cố gắng xác định thời gian cho một cái gì đó không phải là không xác định. Bởi vì máy tính xử lý các tác vụ cả theo yêu cầu và trong nền, nên gần như không thể biết tài nguyên hệ thống nào sẽ có sẵn tại bất kỳ thời điểm nào trong tương lai - và đó là sự sẵn có của tài nguyên hệ thống cần thiết cho bất kỳ tác vụ nào.
Sử dụng một ví dụ khác, giả sử bạn đang chạy nâng cấp chương trình trên máy chủ thực hiện cập nhật cơ sở dữ liệu khá chuyên sâu. Trong quá trình cập nhật này, người dùng sau đó sẽ gửi một yêu cầu đòi hỏi đến một cơ sở dữ liệu khác đang chạy trên hệ thống này. Bây giờ, tài nguyên máy chủ, đặc biệt cho cơ sở dữ liệu, đang phải xử lý các yêu cầu cho cả nâng cấp cũng như truy vấn do người dùng khởi tạo - một kịch bản chắc chắn sẽ gây bất lợi cho thời gian thực hiện. Thay phiên, một người dùng có thể bắt đầu một yêu cầu chuyển tập tin lớn sẽ đánh thuế thông lượng lưu trữ cũng sẽ làm giảm hiệu suất. Hoặc một tác vụ theo lịch trình có thể khởi động để thực hiện quá trình sử dụng nhiều bộ nhớ. Bạn có ý tưởng.
Như, có lẽ, một ví dụ thực tế hơn cho người dùng hàng ngày - xem xét việc chạy Windows Update hoặc quét vi-rút. Cả hai hoạt động này thực hiện các hoạt động chuyên sâu tài nguyên trong nền. Do đó, mỗi tiến trình thực hiện tùy thuộc vào những gì người dùng đang làm vào thời điểm đó. Nếu bạn đang đọc email của mình trong khi điều này chạy, rất có thể nhu cầu về tài nguyên hệ thống sẽ thấp và thanh tiến trình sẽ di chuyển ổn định. Mặt khác, nếu bạn đang thực hiện chỉnh sửa đồ họa thì nhu cầu về tài nguyên hệ thống của bạn sẽ lớn hơn nhiều, điều này sẽ khiến chuyển động của thanh tiến trình bị tâm thần phân liệt.
Nhìn chung, đơn giản là không có quả cầu pha lê. Ngay cả hệ thống cũng không biết nó sẽ tải ở mức nào tại bất kỳ thời điểm nào trong tương lai.
Cuối cùng, nó thực sự không thành vấn đề
Mục đích của thanh tiến trình là, tốt, chỉ ra rằng tiến trình thực sự đang được thực hiện và quá trình tương ứng không được treo. Thật tuyệt khi chỉ báo tiến trình là chính xác, nhưng thông thường nó chỉ là một phiền toái nhỏ khi không. Đối với hầu hết các phần, các nhà phát triển sẽ không dành nhiều thời gian và công sức cho các thuật toán thanh tiến trình bởi vì, thẳng thắn, có nhiều nhiệm vụ quan trọng hơn để dành thời gian cho.
Tất nhiên, bạn có quyền được làm phiền khi một thanh tiến trình nhảy tới 99% hoàn thành ngay lập tức và sau đó khiến bạn phải chờ 5 phút cho một phần trăm còn lại. Nhưng nếu chương trình tương ứng hoạt động tốt trên tổng thể, chỉ cần nhắc nhở bản thân rằng nhà phát triển có các ưu tiên của họ.