$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
From: Jeff Garland (jeff_at_[hidden])
Date: 2006-06-21 21:21:52
Brian Neal wrote:
> We have an application that was using our own custom functions for
> getting the OS time. We were basically representing time as the number
> of milliseconds since the UNIX epoch in an unsigned long, or as the
> number of nanoseconds since the epoch in a 64-bit type.
> 
> We later discovered boost, and cut everything over to
> boost::date_time. This has worked out very, very well and has
> uncovered several time related bugs in our old code. 
Glad it was helpful :-)
> However, we do
> have a small percentage of code that is time critical, and we have
> noticed that calling microsec_clock::univeral_time() is 2.6 times
> slower than our old function, and for this one bit of code that is
> significant.
Ok.
> Looking at the implementation for UNIX like systems, I see that
> create_time() in microsec_time_clock.hpp is calling gettimeofday()
> followed by a call to gmtime() or localtime() as appropriate. I think
> it's this second call that is the difference between our old code and
> boost.
Ok.
> In our time critical chunk of code we are just time tagging events,
> and we aren't concerned about timezone. I was thinking about adding a
> function to our code that called clock_gettime() (which is what our
> old code did), but then constructing a time_type out of that using the
> UNIX epoch for the date part and the results of clock_gettime() for
> the time_duration part, i.e, in pseudo code:
> 
> time_type our_get_time() {
> clock_gettime(CLOCK_REALTIME, ×pec);
> time_duration td = massage(timespec);
> return time_type(unix_epoch, td);
> }
Looks like a solid approach.  Of course you don't have to modify 
Boost.date_time, you can simply extend it with your own clock implementation. 
  Since you'll only ever be calling universal time you only need to write one 
function:
   template<class time_type>
   class gettime_clock
   {
   public:
     typedef typename time_type::date_type date_type;
     typedef typename time_type::time_duration_type time_duration_type;
     typedef typename time_duration_type::rep_type resolution_traits_type;
     //! Get the current day in universal date as a ymd_type
     static time_type universal_time()
     {
       //your code here...
     }
   };
> This still won't be as fast as our old code, because we essentially
> ignored the date part of the times and simply worked with durations
> since the epoch. But I think the killer for us is the call to gmtime,
> which the above avoids.
> 
> Comments? I'm curious why this approach wasn't taken in boost. Was it
> the timezone factor?
> 
> I'm also curious why gettimeofday() was chosen over clock_gettime()?
> Is one more available than the other?
Honestly, I don't remember why at this point.  There is the issue with 
timezone adjustment for the other cases. My guess is portability was a factor 
since gettime_clock is only supported in the POSIX real-time spec, although 
it's probably pretty widespread now.  That said, I'd be willing to improve the 
implementation of microsecond_clock with this change where it is possible -- 
looks like we can tell by checking CLOCK_REALTIME.
If you send me a working implementation I can drop it in and try it out ;-)
Jeff