gettimeofday(2) == bad; clock_gettime(2) == good.
Finally, a technical post I feel worthy of commenting on.
Performance of my application changes from time(3) to gettimeofday(2). Why?
Joe Open Source Developer
Doh! Really common question and should be an FAQ at this point.... or it is, but an under-published FAQ that only the performance wonks seem to know or run into as an issue. In short, gettimeofday(2) == EBAD && clock_gettime(2) == EGOOD. I think the best discussion on this is PHK's post titled Timers and timing, was: MySQL Performance 6.0rc1. Please read. Essentially, FreeBSD's gettimeofday(2) syscall is monotonic, highly accurate and precise, and Leenox's is not. Therefore, Leenox's gettimeofday(2) syscall is faster and less accurate than FreeBSD's. I happen to agree that gettimeofday(2) should be monotonic and I take issue with Leenox's gettimeofday(2) implementation. Monotonic time keeping requires CPU synchronization (which gettimeofday(2) does under FreeBSD and should be done under all operating systems) and will always be slow as a result. Most applications that do not require precise time synchronization across threads and CPUs should use clock_gettime(2) with a clock_id of CLOCK_REALTIME_FAST. Few applications actually need highly precise, highly accurate, monotonic time measurement and instead can skid by with highly precise, accurate, but non-monotomic time keeping. And now you know.
If you want a few additional links to look at the following posts.
Updated June 1, 2008 @20:45:00: I wrote a small time micro-benchmarking program (bench_time.c) to test out various time calls. When in doubt, test. Very interesting results.
% ./bench_time 9079882 | sort -rnk1 Timing micro-benchmark. 9079882 syscall iterations. Avg. us/call Elapsed Name 9.322484 84.647053 gettimeofday(2) 8.955324 81.313291 time(3) 8.648315 78.525684 clock_gettime(2/CLOCK_REALTIME) 8.598495 78.073325 clock_gettime(2/CLOCK_MONOTONIC) 0.674194 6.121600 clock_gettime(2/CLOCK_PROF) 0.648083 5.884515 clock_gettime(2/CLOCK_VIRTUAL) 0.330556 3.001412 clock_gettime(2/CLOCK_REALTIME_FAST) 0.306514 2.783111 clock_gettime(2/CLOCK_SECOND) 0.262788 2.386085 clock_gettime(2/CLOCK_MONOTONIC_FAST) Last value from gettimeofday(2): 1212380080.620649 Last value from time(3): 1212380161 Last value from clock_gettime(2/CLOCK_VIRTUAL): 2.296430000 Last value from clock_gettime(2/CLOCK_SECOND): 1212380338.000000000 Last value from clock_gettime(2/CLOCK_REALTIME_FAST): 1212380243.461081040 Last value from clock_gettime(2/CLOCK_REALTIME): 1212380240.459788612 Last value from clock_gettime(2/CLOCK_PROF): 185.560343000 Last value from clock_gettime(2/CLOCK_MONOTONIC_FAST): 5747219.271879584 Last value from clock_gettime(2/CLOCK_MONOTONIC): 5747216.886509281
Absolutely not what I was expecting, but very interesting none-the-less. clock_gettime(CLOCK_REALTIME_FAST, ...) is most certainly the way to go on FreeBSD. Hopefully this FAQ can be put to rest for a while.
Updated June 2, 2008 @10:45:00: I wrote a small variation to the above program that compares the values returned from the various time calls (bench_clock_realtime.c). On my dev system, CLOCK_REALTIME_FAST updates its values around 600 times a second, which is likely accurate enough for most applications, but may not be in all environments.
% ./bench_clock_realtime 9079882 | sort -rnk1 clock realtime micro-benchmark. 9079882 syscall iterations. Avg. us/call Elapsed Name 9.317078 84.597968 gettimeofday(2) 8.960372 81.359120 time(3) 8.776467 79.689287 clock_gettime(2/CLOCK_REALTIME) 0.332357 3.017763 clock_gettime(2/CLOCK_REALTIME_FAST) 0.311705 2.830246 clock_gettime(2/CLOCK_SECOND) Value from time(3): 1212427374 Last value from gettimeofday(2): 1212427293.590511 Equal: 0 Last value from clock_gettime(2/CLOCK_SECOND): 1212427460.000000000 Equal: 9079878 Last value from clock_gettime(2/CLOCK_REALTIME_FAST): 1212427457.656410126 Equal: 9078198 Last value from clock_gettime(2/CLOCK_REALTIME): 1212427454.639076390 Equal: 0 % irb >> tot = 9079882 => 9079882 >> eq = 9078198 => 9078198 >> tot - eq => 1684 >> time = 3.017763 => 3.017763 >> (tot - eq) / time => 558.029242190324
