
Le 12/05/13 00:22, Howard Hinnant a écrit :
On May 10, 2013, at 1:45 PM, "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr> 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'; }