2012-01-15 33 views
6

Tôi có một ứng dụng, trong khi thực hiện tác vụ nền, hiển thị thanh tiến trình có tính "thời gian còn lại ước tính" (ví dụ: "5 giây còn lại") và "thời gian hoàn thành ước tính" (ví dụ: "hoàn thành lúc 12:59 : 59 "), hoặc như tôi gọi nó là ETA.Làm cách nào để loại bỏ "jitter" khỏi tính toán "thời gian còn lại ước tính" (và ETA) của tôi?

Thuật toán để tính toán ETA này về cơ bản có "tiến độ trung bình" theo thời gian:
1. Mỗi sự kiện tiến trình được thêm vào hàng đợi với thời gian hiện tại.
2. Sau một khoảng thời gian nhất định (ví dụ 10 giây), các mục sẽ bị xóa khỏi hàng đợi.
3. ETA được ngoại suy từ các mục đầu tiên và cuối cùng trong hàng đợi.
Mã nguồn có sẵn nếu bạn quan tâm: ETACalculator.cs

Tuy nhiên, có một vấn đề jitter. Khi mỗi sự kiện tiến trình được thêm vào tính toán, ETA sẽ được cập nhật một chút. Giả sử rằng ETA chỉ thay đổi theo số 0.1s. Jitter nhỏ này dễ dàng gây ra ETA để "rung". Ví dụ, thay vì nhìn thấy một sự tiến triển suôn sẻ từ 5s, 4s, 3s, vv ..., tôi thấy 5-5-5-4-5-4-5-4-5-4-4-4.

Tôi đã nghĩ đến việc chỉ giảm các bản cập nhật xuống còn 1 giây, nhưng sau đó thanh tiến trình kém trơn tru hơn, và tôi cũng thực sự muốn "chậm" thực tế được hiển thị theo thời gian thực.

Tôi đang gặp khó khăn trong việc đưa ra một thuật toán đơn giản làm giảm jitter tăng vọt này. Làm thế nào tôi có thể loại bỏ jitter?

+0

Winforms? WPF? Thứ gì khác? Bạn có thể đăng mã có liên quan không? – Oded

+3

Bắt buộc [tham chiếu xkcd] (http://xkcd.com/612/). – Ani

+0

Chỉ cập nhật tiến trình nếu nó bị giảm. (ví dụ: không thay đổi lại thành 5 nếu chúng tôi hiện đang ở trên 4). –

Trả lời

9

Tách riêng tiến độ jitter thực tếtiến trình hiển thị thành hai biến riêng biệt.

Cập nhật tiến trình dữ dội như bạn làm ngay bây giờ.

Với khoảng thời gian thông thường (tương đối nhanh), hãy cập nhật tiến trình được hiển thị thành cách tiếp cận tiến độ thực tế.

Một thuật toán phương pháp đơn giản sẽ được trung bình hai giá trị

display_progress = (display_progress + actual_progress)/2 

Điều này sẽ làm giảm giá trị để phản ánh giá trị quá khứ và không chỉ là giá trị ngay lập tức.

Bạn cũng có thể tinh chỉnh êm ái bằng cách sử dụng:

display_progress = (P) * display_progress + (1.0-P) * actual_progress 

đâu P là một giá trị không đổi giữa 0.01.0.

Edit:

Đây là một trong nhiều bộ lọc có thể được sử dụng. Điều này là tốt đẹp ở chỗ nó không đòi hỏi phải có sổ sách kế toán nhiều.

Tuy nhiên, việc nhận được đầu ra hoàn hảo sẽ không phải là tùy chọn vì lỗ hổng nằm trong số đầu vào của bạn. Sự khác biệt giữa "jitter" và "slowdowns thực tế" chỉ có thể quan sát được sau nó đã xảy ra.

+1

Ý tưởng hay (bộ lọc thông thấp IIR đầu tiên), nhưng điều này nên được thực hiện trên biến "thời gian còn lại", chứ không phải biến "% tiến độ". –

+0

Tôi có thể thấy điều này sẽ "làm mịn" tiến trình như thế nào, và nó có thể là một bổ sung tốt cho tính toán tiến độ của tôi. Nhưng tôi nghĩ rằng điều này sẽ vẫn còn bị jitter trong ngoại suy ETA. Ngay cả khi jitter chỉ là '0.00001', điều đó sẽ hiển thị khi ETA nằm giữa' 5.00000' và '4.99999'. Xin lỗi câu hỏi của tôi không làm rõ điều này; Tôi sẽ cập nhật nó. –

2

Không rõ ràng về thuật toán của bạn mà không nhìn thấy mã, nhưng khi bạn cập nhật ETA của mình trước tiên hãy kiểm tra ETA hiện tại và chỉ cập nhật nếu giá trị mới thấp hơn giá trị cũ.

+1

Tôi đã cập nhật liên kết tới [ETACalculator.cs] (https://github.com/scottrippey/Progression/blob/master/Progression/Extras/ETACalculator.cs), nếu bạn quan tâm. Tuy nhiên, trong tình huống của tôi, tiến trình có thể chậm lại, trong trường hợp này tôi muốn hiển thị một ETA chính xác. –

Các vấn đề liên quan