While looking into LWG 3741 I came up with this small change to chrono::abs, which reduces how much work the compiler does to compile it, but makes the code less clear. The current implementation is very easy to understand, and compiling chrono::abs probably isn't a hotspot in anybody's build. Is this worth it?
-- >8 -- This change manually inlines the call to duration::zero, the comparison using chrono::operator< with duration arguments, the call to duration::operator- (and the common_type instantiation it does). This also avoids calling the duration(const duration<R2,P2>&) constructor (and its constraint checks). By performing the arithmetic operations directly on the Rep value we improve compilation throughput and also runtime performance for unoptimized builds. libstdc++-v3/ChangeLog: * include/bits/chrono.h (chrono::abs): Optimize. --- libstdc++-v3/include/bits/chrono.h | 42 +++++++++++++++--------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/libstdc++-v3/include/bits/chrono.h b/libstdc++-v3/include/bits/chrono.h index 05987ca09df..99d47503af3 100644 --- a/libstdc++-v3/include/bits/chrono.h +++ b/libstdc++-v3/include/bits/chrono.h @@ -317,6 +317,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { }; #endif // C++20 + /// duration_values + template<typename _Rep> + struct duration_values + { + static constexpr _Rep + zero() noexcept + { return _Rep(0); } + + static constexpr _Rep + max() noexcept + { return numeric_limits<_Rep>::max(); } + + static constexpr _Rep + min() noexcept + { return numeric_limits<_Rep>::lowest(); } + }; + #if __cplusplus >= 201703L # define __cpp_lib_chrono 201611L @@ -365,11 +382,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Rep, typename _Period> constexpr enable_if_t<numeric_limits<_Rep>::is_signed, duration<_Rep, _Period>> - abs(duration<_Rep, _Period> __d) + abs(duration<_Rep, _Period> __d) noexcept(is_arithmetic_v<_Rep>) { - if (__d >= __d.zero()) - return __d; - return -__d; + if (_Rep __c = __d.count(); __c < duration_values<_Rep>::zero()) + return duration<_Rep, _Period>(-__c); + return __d; } // Make chrono::ceil<D> also usable as chrono::__detail::ceil<D>. @@ -399,23 +416,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } #endif // C++17 - /// duration_values - template<typename _Rep> - struct duration_values - { - static constexpr _Rep - zero() noexcept - { return _Rep(0); } - - static constexpr _Rep - max() noexcept - { return numeric_limits<_Rep>::max(); } - - static constexpr _Rep - min() noexcept - { return numeric_limits<_Rep>::lowest(); } - }; - /// @cond undocumented template<typename _Tp> -- 2.37.2