2014-04-30 14 views
8

Tôi đã thực hiện một ứng dụng thử nghiệm nhỏ trong C# đặt DateTime.Now và bắt đầu một StopWatch. Cứ mười giây một lần tôi in _stopwatch.Elapsed.TotalMilliseconds(DateTime.Now - _startTime).TotalMilliseconds.Tại sao DateTime.Now và StopWatch trôi dạt?

Trong khi tôi không mong đợi hai giống hệt nhau, tôi đã ngạc nhiên khi thấy chúng phân kỳ tuyến tính khoảng một phần nghìn giây mỗi 20 giây. Tôi giả sử DateTime.Now gọi đồng hồ hệ thống, trong khi StopWatch thực hiện một số loại tích lũy nào?

Mẫu đầu ra:

StopWatch : 0,2 DateTime : 1,0 Diff : 0,81 
StopWatch : 10000,5 DateTime : 10002,6 Diff : 2,04 
(...) 
StopWatch : 2231807,5 DateTime : 2231947,7 Diff : 140,13 
StopWatch : 2241809,5 DateTime : 2241950,2 Diff : 140,70 

Full source: https://gist.github.com/knatten/86529563122a342de6bb

Output: https://gist.github.com/knatten/84f9be9019ee63119ee2

+0

suy nghĩ về nó ... bạn không thể gọi họ là cả hai trên cùng một dòng ở chính xác cùng một thời điểm ... do đó, vâng, trong giờ của bạn, thời gian cần thiết để in thông tin cho datetime, và THEN in thông tin cho StopWatch, bất kể chúng gần như thế nào (ngay sau cái kia), trên 20 giây, sẽ hiển thị một sự khác biệt tương đối nhỏ (1ms) ... – MaxOvrdrv

+4

@MaxOvrdrv Trong khi điều này có thể giải thích cho một sự khác biệt ban đầu, nó sẽ không gây ra trôi dạt phù hợp như quy định trong OP. – Ashigore

+1

@Ashigore bạn đang phải ... nó phải là sự khác biệt cùng nhìn thấy trong tất cả các bản in ... tôi không biết sau đó ... có thể pin đồng hồ nội bộ của mình đang chạy thấp trên điện? ;) – MaxOvrdrv

Trả lời

3

Câu trả lời tương đối thẳng về phía trước.

  • Đồng hồ bấm giờ đếm bộ xử lý bằng bộ đếm hiệu suất, một cơ chế khác nhau giữa các bộ xử lý.
  • Truy vấn ngày giờ đồng hồ hệ thống - đồng hồ hệ thống được cập nhật định kỳ bằng các cửa sổ sử dụng đầu ra từ đồng hồ tinh thể (có thể là thạch anh) trên bo mạch chủ của bạn.

Tất cả các đồng hồ trôi dạt và hai cơ chế thời gian khác nhau này sẽ trôi theo các tốc độ khác nhau.

Dưới mui xe, Stopwatchuses this API

Lớp Stopwatch hỗ trợ các thao tác của quầy hiệu suất thời gian liên quan đến bên trong mã được quản lý.Cụ thể, trường Tần số và phương pháp GetTimestamp có thể được sử dụng thay cho Truy vấn API của Win32 không được quản lýFrequency và QueryPerformanceCounter.

DateTimeuses this API

+2

Không chỉ làm đồng hồ vật lý trôi dạt, mà còn là DateTime (Utc) Bây giờ có thể được điều chỉnh thêm vào nguồn thời gian mạng. Xem ví dụ [Câu trả lời của Hans Passant] (http://stackoverflow.com/a/19736972/709537) cho một câu hỏi tương tự. –

3

DateTime.Now bọ ve mỗi vài mili giây. Ngoài ra, tốc độ mà nó đánh dấu không cố định từ máy này sang máy khác. Trên các hệ thống cửa sổ hiện đại, bạn có thể mong đợi rằng độ phân giải đánh dấu sẽ vào khoảng 100 bọ ve mỗi giây. Mặt khác, StopWatch truy vấn phần cứng CPU để có độ chính xác cao. Trên thực tế, bạn có thể nhận được độ phân giải StopWatch sử dụng Stopwatch.Frequency.

Tôi không biết cả hai điều trên, cho đến khi tôi đọc một bài đăng thú vị về Eric Lippert, về các lỗi tiêu chuẩn hiệu năng chung, vui lòng xem tại đây here. Đây thật là một bài viết tuyệt vời.

+0

Bằng cách đánh dấu, bạn có nghĩa là DateTime.Now đang tích lũy và tích lũy không? Tôi hy vọng nó sẽ truy vấn đồng hồ hệ thống. – knatten

+0

Như tôi đã hiểu, cả hai DateTime.Now và StopWatch ticks nhưng ở mức giá khác nhau. – Christos

+0

Họ đánh dấu ở các mức giá khác nhau, nhưng có vẻ như Đồng hồ bấm giờ tích lũy ve, trong khi DateTime truy vấn lại thời gian hệ thống, xem câu trả lời của Gusdor. – knatten

2

Stopwatch là nhiều hơn nữa chính xác hơn DateTime đó sẽ chiếm sự khác biệt

Từ MSDN:

Các biện pháp Stopwatch trôi qua thời gian bằng cách đếm timer bọ ve trong cơ chế hẹn giờ cơ bản. Nếu phần cứng và hệ điều hành được cài đặt hỗ trợ bộ đếm hiệu năng có độ phân giải cao, thì lớp Đồng hồ bấm giờ sử dụng bộ đếm đó để đo thời gian trôi qua. Nếu không, lớp Đồng hồ bấm giờ sử dụng bộ hẹn giờ hệ thống để đo thời gian trôi qua. Sử dụng các trường Frequency và IsHighResolution để xác định độ chính xác và độ phân giải của việc thực hiện thời gian Đồng hồ bấm giờ.

+0

Vì vậy Đồng hồ bấm giờ chính xác hơn, nhưng cái nào chính xác hơn? Cả hai đều tích lũy bọ ve hoặc DateTime.Now có truy vấn đồng hồ hệ thống không? Trong trường hợp đó, chúng tôi có thể có Đồng hồ bấm giờ chính xác hơn, nhưng là một DateTime chính xác hơn. – knatten

+1

Độ chính xác sẽ thay đổi theo cấu hình phần cứng. – Gusdor

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