Boost C++ Libraries: Ticket #11806: microsec_clock::universal_time() is needlessly slow https://svn.boost.org/trac10/ticket/11806 <p> The <a href="http://www.boost.org/doc/libs/1_55_0/doc/html/date_time/posix_time.html">documentation</a> for <code>microsec_clock::universal_time()</code> says: </p> <blockquote class="citation"> <p> Get the UTC time using a sub second resolution clock. On Unix systems this is implemented using GetTimeOfDay. </p> </blockquote> <p> In fact it is implemented partly using <code>gettimeofday()</code> but also <code>gmtime_r()</code>. Once you unwrap all the layers, the flow is something like this: </p> <blockquote> <p> sec,nsec = gettimeofday() date,time = gmtime(sec) sec,nsec = ptime(date,time) return sec+nsec/1000 </p> </blockquote> <p> The problem is that <code>gmtime_r()</code> is very slow, relative to the other operations involved here, and it is completely unnecessary. A call to <code>gettimeofday()</code> on Unix is all you need to implement <code>universal_time()</code>. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/11806 Trac 1.4.3 James E. King, III Sat, 06 Jan 2018 15:02:15 GMT owner, status changed https://svn.boost.org/trac10/ticket/11806#comment:1 https://svn.boost.org/trac10/ticket/11806#comment:1 <ul> <li><strong>owner</strong> changed from <span class="trac-author">az_sw_dude</span> to <span class="trac-author">James E. King, III</span> </li> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">assigned</span> </li> </ul> Ticket James E. King, III Sat, 06 Jan 2018 15:31:19 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/11806#comment:2 https://svn.boost.org/trac10/ticket/11806#comment:2 <ul> <li><strong>status</strong> <span class="trac-field-old">assigned</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">wontfix</span> </li> </ul> <p> I benchmarked calling the current implementation (boost 1.66.0) in release mode on linux (ubuntu artful) 1M times and each call takes less than 100ns: </p> <pre class="wiki">test: // benchmark for trac 11806 { check("calling microsec_clock::universal_time 1000000 times", true); boost::timer::auto_cpu_timer t; for (size_t i = 0; i &lt; 1000000; ++i) { ptime x = microsec_clock::universal_time(); } return 0; } results: jking@ubuntu:~/boost/libs/date_time/test$ ../../../bin.v2/libs/date_time/test/testmicrosec_time_clock.test/gcc-gnu-7/release/threadapi-pthread/testmicrosec_time_clock Pass :: calling microsec_clock::universal_time 1000000 times 0.088597s wall, 0.090000s user + 0.000000s system = 0.090000s CPU (101.6%) jking@ubuntu:~/boost/libs/date_time/test$ ../../../bin.v2/libs/date_time/test/testmicrosec_time_clock.test/gcc-gnu-7/release/threadapi-pthread/testmicrosec_time_clock Pass :: calling microsec_clock::universal_time 1000000 times 0.103956s wall, 0.100000s user + 0.000000s system = 0.100000s CPU (96.2%) jking@ubuntu:~/boost/libs/date_time/test$ ../../../bin.v2/libs/date_time/test/testmicrosec_time_clock.test/gcc-gnu-7/release/threadapi-pthread/testmicrosec_time_clock Pass :: calling microsec_clock::universal_time 1000000 times 0.096352s wall, 0.090000s user + 0.000000s system = 0.090000s CPU (93.4%) </pre><p> I then changed the code such that if the clock source is universal time (i.e. gmtime_r) passed into create_time, we take (what I thought would be a) shortcut: </p> <pre class="wiki">#if defined(BOOST_HAS_GETTIMEOFDAY) timeval tv; if (-1 == gettimeofday(&amp;tv, 0)) { //gettimeofday does not support TZ adjust on Linux. boost::throw_exception(std::runtime_error("gettimeofday failed")); } if (universal) { // if the source is UTC we can take a fast shortcut here instead // of calling gmtime_r, which is slow (see Boost Trac 11806) static date_type posix_epoch(1970, 1, 1); static uint64_t res = resolution_traits_type::res_adjust(); return time_type(date_type(1970, 1, 1), time_duration_type(0, 0, tv.tv_sec, (static_cast&lt;uint64_t&gt;(tv.tv_usec) * res) / 1000000ull)); } std::time_t t = tv.tv_sec; boost::uint32_t sub_sec = tv.tv_usec; #elif defined(BOOST_HAS_FTIME) </pre><p> This slowed down the program so much I didn't even let it finish. Asking for a ptime based on a large number of seconds is incredibly inefficient. So I am resolving this as wontfix, unless you have a better suggestion for implementing it. </p> Ticket