Saya baru saja mengalami beberapa perilaku tak terduga dengan DateTime.UtcNow saat melakukan beberapa pengujian unit. Tampaknya saat Anda memanggil DateTime.Now/UtcNow secara berurutan, tampaknya memberikan Anda nilai yang sama untuk interval waktu yang lebih lama dari yang diharapkan, daripada menangkap kenaikan milidetik yang lebih tepat.
Saya tahu ada kelas Stopwatch yang lebih cocok untuk melakukan pengukuran waktu yang tepat, tetapi saya ingin tahu apakah seseorang dapat menjelaskan perilaku ini di DateTime? Apakah ada presisi resmi yang didokumentasikan untuk DateTime.Now (misalnya, tepat dalam 50 md?)? Mengapa DateTime.Now dibuat kurang tepat daripada yang dapat ditangani oleh kebanyakan jam CPU? Mungkin itu hanya dirancang untuk CPU denominator umum terendah?
public static void Main(string[] args)
{
var stopwatch = new Stopwatch();
stopwatch.Start();
for (int i=0; i<1000; i++)
{
var now = DateTime.Now;
Console.WriteLine(string.Format(
"Ticks: {0}\tMilliseconds: {1}", now.Ticks, now.Millisecond));
}
stopwatch.Stop();
Console.WriteLine("Stopwatch.ElapsedMilliseconds: {0}",
stopwatch.ElapsedMilliseconds);
Console.ReadLine();
}
Jawaban:
Jam yang bagus harus tepat dan akurat ; itu berbeda. Seperti lelucon lama, jam yang dihentikan persis dua kali sehari, jam yang lambat satu menit tidak pernah akurat setiap saat. Tetapi jam yang lambat satu menit selalu tepat ke menit terdekat, sedangkan jam yang berhenti tidak memiliki presisi yang berguna sama sekali.
Mengapa DateTime harus tepat , katakanlah satu mikrodetik padahal tidak mungkin akurat ke mikrodetik? Kebanyakan orang tidak memiliki sumber sinyal waktu resmi yang akurat untuk mikrodetik. Oleh karena itu memberikan enam digit setelah tempat desimal ketepatan , lima yang terakhir adalah sampah akan berbohong .
Ingat, tujuan DateTime adalah untuk mewakili tanggal dan waktu . Pengaturan waktu presisi tinggi bukanlah tujuan DateTime; seperti yang Anda catat, itulah tujuan StopWatch. Tujuan DateTime adalah untuk mewakili tanggal dan waktu untuk tujuan seperti menampilkan waktu saat ini kepada pengguna, menghitung jumlah hari hingga Selasa depan, dan seterusnya.
Singkatnya, "jam berapa sekarang?" dan "berapa lama waktu yang dibutuhkan?" adalah pertanyaan yang sama sekali berbeda; jangan gunakan alat yang dirancang untuk menjawab satu pertanyaan untuk menjawab pertanyaan lainnya.
Terima kasih atas pertanyaannya; ini akan menjadi artikel blog yang bagus! :-)
sumber
Ketepatan DateTime agak spesifik untuk sistem yang dijalankannya. Presisi terkait dengan kecepatan sakelar konteks, yang cenderung sekitar 15 atau 16 ms. (Di sistem saya, sebenarnya sekitar 14 ms dari pengujian saya, tetapi saya telah melihat beberapa laptop di mana akurasi mendekati 35-40 ms.)
Peter Bromberg menulis artikel tentang pewaktuan kode presisi tinggi di C #, yang membahas hal ini.
sumber
Saya ingin Datetime yang tepat. Sekarang :), jadi saya memasak ini:
sumber
Dari MSDN Anda akan menemukan bahwa
DateTime.Now
memiliki perkiraan resolusi 10 milidetik pada semua sistem operasi NT.Presisi sebenarnya bergantung pada perangkat keras. Presisi yang lebih baik dapat diperoleh dengan menggunakan
QueryPerformanceCounter
.sumber
Untuk apa nilainya, selain benar-benar memeriksa sumber .NET, Eric Lippert memberikan komentar pada pertanyaan SO ini yang mengatakan bahwa DateTime hanya akurat hingga kira-kira 30 ms. Alasan tidak akuratnya nanodetik, dalam kata-katanya, adalah karena "tidak perlu".
sumber
Dari dokumentasi MSDN :
Mereka juga mengklaim bahwa perkiraan resolusi pada Windows NT 3.5 dan yang lebih baru adalah 10 ms :)
sumber
Akibatnya, panggilan berulang ke properti Now dalam interval waktu yang singkat, seperti dalam satu loop, dapat mengembalikan nilai yang sama.
Tautan MSDN
sumber