Boost logo

Boost :

Subject: Re: [boost] [chrono/date] conversion between concrete dates
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2013-05-12 05:44:13


Le 12/05/13 00:22, Howard Hinnant a écrit :
> On May 10, 2013, at 1:45 PM, "Vicente J. Botet Escriba" <vicente.botet_at_[hidden]> wrote:
>
>> When I add validation on the source date format I get
>>
>> clang 3.2
>> * empty field->serial ~6.3ns.
>> * field->serial ~13.4ns.
>> * empty serial->field ~1ns.
>> * serial->field ~17.9ns.
>>
>> gcc-4.8.0
>> * empty field->serial ~7.5ns.
>> * field->serial ~15.7ns.
>> * empty serial->field ~1ns.
>> * serial->field ~21.7ns.
> I've been experimenting with adding validation today. I'm guessing that all of your validation is in a translation unit hidden from the testing loop. Is that correct?
>
> I've been putting my validation in a header because I want to make it constexpr, and constexpr stuff has weak linkage. The motivation for making it constexpr is that for any part of the validation that involves compile-time information, the validation happens at compile time.
>
> And my first experiments today involve putting some of the validation back into the unit specifiers, in contrast to the direction I was heading earlier.
>
>
Hi,

after making validation *constexpr* I'm getting better results, but
there is yet a difference.

checked: volatile ymd_date dt = ymd_date(year(y), month(m,
check), day(d,check), check);
unchecked: volatile ymd_date dt = ymd_date(year(y), month(m),
day(d));

clang 3.2
checked ymd 1.75081
unchecked ymd 0.0923393
ENCODE empty 0.0895197

gcc-4.8.0
checked ymd 1.42277
unchecked ymd 0.116654
ENCODE empty 0.113943

See the test bellow.

Best,
Vicente

============

const int Ymin = 1900;
const int Ymax = 2100;

void unchecked_ymd_dcl()
{
   int count = 0;
   auto t0 = boost::chrono::high_resolution_clock::now();
   for (int y = Ymin; y <= Ymax; ++y)
   {
     bool is_l = year(y).is_leap();
     for (int m = 1; m <= 12; ++m)
     {
       int last = month(m).days_in(is_l).count();
       for (int d = 1; d <= last; ++d)
       {
         volatile ymd_date dt = ymd_date(year(y), month(m), day(d));
         ++count;
       }
     }
   }
   auto t1 = boost::chrono::high_resolution_clock::now();
   typedef boost::chrono::duration<float, boost::nano> sec;
   auto encode = t1 - t0;
   std::cout << "unchecked ymd " << sec(encode).count() / count << '\n';
}
void checked_ymd_dcl()
{
   int count = 0;
   auto t0 = boost::chrono::high_resolution_clock::now();
   for (int y = Ymin; y <= Ymax; ++y)
   {
     bool is_l = year(y).is_leap();
     for (int m = 1; m <= 12; ++m)
     {
       int last = month(m).days_in(is_l).count();
       for (int d = 1; d <= last; ++d)
       {
         volatile ymd_date dt = ymd_date(year(y), month(m, check),
day(d,check), check);
         ++count;
       }
     }
   }
   auto t1 = boost::chrono::high_resolution_clock::now();
   typedef boost::chrono::duration<float, boost::nano> sec;
   auto encode = t1 - t0;
   std::cout << "checked ymd " << sec(encode).count() / count << '\n';
}
void empty_encoding_perf()
{
   int count = 0;
   auto t0 = boost::chrono::high_resolution_clock::now();
   for (int y = Ymin; y <= Ymax; ++y)
   {
     bool is_l = year(y).is_leap();
     for (int m = 1; m <= 12; ++m)
     {
       int last = month(m).days_in(is_l).count();
       for (int d = 1; d <= last; ++d)
       {
         ++count;
       }
     }
   }
   auto t1 = boost::chrono::high_resolution_clock::now();
   typedef boost::chrono::duration<float, boost::nano> sec;
   auto encode = t1 - t0;
   std::cout << "empty " << sec(encode).count() / count << '\n';
}


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk