2012-03-14 30 views
5

Tôi đã viết một đoạn mã như sau:Giá trị bộ đếm AverageTimer32 trở thành số không

Để thử nghiệm tôi gọi phương thức ComputeAndLog và trong màn hình hiệu suất tôi có thể thấy giá trị trung bình khác 0. Tuy nhiên ngay sau khi tôi kết thúc thử nghiệm, giá trị bộ đếm hiệu năng trung bình giảm xuống 0. Bất kỳ ý tưởng tại sao thats trường hợp?

Có lẽ tôi đang sử dụng bộ đếm sai?

Yêu cầu tôi có là tôi có một hàm và tôi phải tính toán trung bình, mất bao nhiêu thời gian để hoàn thành. Một cái gì đó như dưới đây:

void ComputeAndLog() 
{ 
    Stopwatch stopWatch = Stopwatch.StartNew(); 
    FunctionWhoseAveragetTimeIsToBeMeasured(); 
    write_counter(stopWatch.ElapsedTicks); 
} 

void write_counter(long timeForCompletion) 
{ 
    averageTimeCounter.IncrementBy(timeForCompletion); 
    averageBaseCounter.Increment(); 
} 

Cảm ơn xoxo

+1

Socrates: mức tăng trung bình là bao nhiêu? –

+0

Xin lỗi tôi đã không nhận được câu hỏi đó. Có lẽ tôi đang sử dụng truy cập sai? Tôi đã cập nhật mã ban đầu với yêu cầu tôi có. –

+0

Đây là thời gian trung bình trong suốt thời gian kể từ lần đo cuối cùng. Nếu bạn không đăng nhập bất cứ điều gì nó sẽ trở thành số không như thời gian trung bình là không xác định (đơn giản hóa bằng không). – Guvante

Trả lời

4

Các AverageTimer32/64 không tính toán tỷ lệ trung bình của tất cả các phép đo bạn thực hiện. Thay vào đó, nó cung cấp khẩu phần đo lường của bạn cho số lượng hoạt động bạn đã đo.

Về cơ bản, vấn đề với mã của bạn là thực tế bạn đang sử dụng bộ hẹn giờ mới mỗi lần bạn thực hiện phép đo.

Để hiểu cách trình hoạt động của AverageTimer, có thể hữu ích khi hiểu công thức đằng sau nó. Điều này cũng giải đáp tại sao người ta cần một AverageBase để sử dụng một AverageTimer.

Công thức cho AverageTimer là như sau:

((N1 - N0)/F)/(B1 - B0) 

với

  • N1 đọc hiện tại thời điểm t (AverageTimer)
  • N0 đọc trước đó, tại t - 1 (AverageTimer)
  • Bộ đếm dòng B1 tại t (AverageBase)
  • B0 truy cập trước, tại t - 1 (Cơ sở trung bình)
  • F Yếu tố để tính toán ve/giây

Tóm lại các công thức mất thời gian hiện tại trong tích tắc và trừ trước đó. Kết quả chia cho hệ số F cho bạn thời gian bạn vận hành chạy kể từ lần đo cuối cùng được thực hiện tại t-1.

Bây giờ bạn chia số này cho bộ đếm hiện tại trừ đi bộ đếm trước đó. Điều này có thể thường là một. Kết quả là bạn có thời gian hoạt động trung bình cho một phép đo.

Sử dụng AverageBase bây giờ bạn có thể vượt qua các điểm đo khác nhau. Hãy nghĩ về một trường hợp mà bạn có thể đặt bộ đếm chỉ mỗi hoạt động thứ mười mà bạn thực hiện. Vì phép đo cuối cùng của bạn, bạn sẽ tăng Bộ thu thập trung bình bằng phép đo thời gian mới cho tất cả mười phép toán nhưng tăng số lượng AverageBase lên 10. Cuối cùng, bạn sẽ nhận được thời gian trung bình cho một hoạt động (ngay cả khi bạn đã đo trên tất cả mười cuộc gọi hoạt động).

Nhìn vào ví dụ mã bạn gửi luôn là sự khác biệt từ bộ đếm thời gian bắt đầu đến giờ kết thúc. Hãy để đây là một loạt các con số như 10, 9, 8, 7, 6 trong khi tăng AverageBase lên 1.

Đối với việc đo lường thứ hai bạn biết sẽ nhận được kết quả sau:

(9-10)/F/(10) = -1/F/1

Với F là 1 vì đơn giản bạn sẽ nhận được -1 là kết quả.

Các giá trị đúng để nộp tuy nhiên nên

10, 19, 27, 34, 40

Một lần nữa ví dụ tương tự, chúng tôi sẽ nhận được

(19 - 10)/F/(1 - 0) = 9/F/1

Một lần nữa, với F là 1 bạn sẽ có thời gian trung bình là 9 cho hoạt động của bạn. Như bạn có thể thấy, giá trị tiếp theo được đo cần phải lớn hơn giá trị trước đó để AverageTimer hoạt động chính xác.

Trong ví dụ của bạn, bạn có thể sử dụng Đồng hồ bấm giờ toàn cầu. Thay vì bắt đầu nó mới, sử dụng Start() (không khởi động lại()). Như đã thấy ở trên, bộ đếm sẽ tính toán sự khác biệt về thời gian trong nội bộ. Bằng cách đó bạn sẽ nhận được các phép đo chính xác.

Đi tới số 0 cũng có ý nghĩa, khi bạn đã hoàn thành thử nghiệm hoặc chương trình của bạn kết thúc, bộ đếm có thể sẽ bị đóng và không cung cấp bất kỳ giá trị nào nữa. Bạn có thể thực hiện thủ công bằng cách gọi phương thức Close() trên bộ đếm.

+0

Tôi không nghĩ câu trả lời này là chính xác. Trong câu hỏi, N luôn luôn * tăng lên * bởi các dấu tích đã trôi qua. Vì vậy, không thể cho N1 nhỏ hơn N0 (như trong ví dụ đầu tiên). Và do đó kết luận còn lại là (có thể) cũng không chính xác. –

0

Tôi gặp sự cố tương tự. Tôi đã có một đầu ra tốt trong PerformanceMonitor bởi AverangeCounter. Nhưng trong chương trình một hoạt động NextValue luôn luôn trả về 0. Bằng cách này trong ElapsedTime truy cập cùng một giá trị trả về hoạt động mà tôi muốn.

Sau đó, tôi hiểu cốt lõi của AverageTimer32 (tôi hy vọng). Bạn không nên hy vọng rằng AverageTimer32 sẽ hiển thị thời gian trung bình của một số công việc. Nó chỉ là hẹn giờ thời gian trung bình cho một hoạt động và hiển thị nó. Nếu không có công việc đang diễn ra hơn là không có thời gian hoạt động tồn tại và bạn sẽ có 0 là giá trị của bộ đếm.

nếu tôi sử dụng NextValue mỗi khi tôi thêm bọ để phản hồi số giây (vì tôi hiểu nó trả về giá trị cuối cùng, không phải giá trị trung bình. Một bộ đếm AverageTimer32 có tên mà bất kỳ ai cũng có thể hiểu). Và nếu tôi cache nó sau đó tôi có thể chuyển đổi nó ở dạng dễ đọc hơn và sử dụng nó như giá trị của truy cập trong chương trình (nếu bạn hỏi NextValue ngay sau đó trong lần thứ hai bạn nhận được 0).

Ngoài ra tôi muốn sửa câu trả lời trước đó. Bạn nên sử dụng

10, 9, 8, 7, 6

thay vì

10, 19, 27, 34, 40

khi bạn sử dụng phương pháp TăngBởi và

10, 19, 27, 34, 40

khi bạn đặt Đồng hồ bấm giờ.GetTimestamp() theo cách thủ công trong RawValue.

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