Boost logo

Boost Users :

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, &timespec);
> 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


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net