From: Aravind Anbudurai Date: Fri, 1 Jul 2016 17:10:43 +0000 (-0700) Subject: Make AutoTimer work with std::chrono::duration instead of seconds with type double X-Git-Tag: 2016.07.26~90 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=0b14cc4f48bebe930814601f9c11e01ec733bf81;p=folly.git Make AutoTimer work with std::chrono::duration instead of seconds with type double Summary: Currently, AutoTimer outputs duration as a double with seconds as units. This is limiting and I'm making it return std::chrono::duration. Users can specify the type with DurationType. This is needed for me because the library that I am going to use inside the callback I pass in using chrono::duration and it feels hacky to go from duration -> double -> duration. Reviewed By: yfeldblum Differential Revision: D3506557 fbshipit-source-id: 0a5e9e16181bfac3a10df6a253716c0499cff5df --- diff --git a/folly/experimental/AutoTimer.h b/folly/experimental/AutoTimer.h index 20c5156d..d51be4a2 100644 --- a/folly/experimental/AutoTimer.h +++ b/folly/experimental/AutoTimer.h @@ -45,8 +45,9 @@ struct GoogleLogger; * "Foo() completed in 4.3 seconds" * * You can customize what you use as the logger and clock. The logger needs - * to have an operator()(StringPiece, double) that gets a message and a duration - * (in seconds). The clock needs to model Clock from std::chrono. + * to have an operator()(StringPiece, std::chrono::duration) that + * gets a message and a duration. The clock needs to model Clock from + * std::chrono. * * The default logger logs usings glog. It only logs if the message is * non-empty, so you can also just use this class for timing, e.g.: @@ -60,9 +61,11 @@ template < class Clock = std::chrono::high_resolution_clock> class AutoTimer final { public: + using DoubleSeconds = std::chrono::duration; + explicit AutoTimer( std::string&& msg = "", - double minTimetoLog = 0.0, + const DoubleSeconds& minTimetoLog = DoubleSeconds::zero(), Logger&& logger = Logger()) : destructionMessage_(std::move(msg)), minTimeToLog_(minTimetoLog), @@ -79,18 +82,18 @@ class AutoTimer final { log(destructionMessage_); } - double log(StringPiece msg = "") { + DoubleSeconds log(StringPiece msg = "") { return logImpl(Clock::now(), msg); } template - double log(Args&&... args) { + DoubleSeconds log(Args&&... args) { auto now = Clock::now(); return logImpl(now, to(std::forward(args)...)); } template - double logFormat(Args&&... args) { + DoubleSeconds logFormat(Args&&... args) { auto now = Clock::now(); return logImpl(now, format(std::forward(args)...).str()); } @@ -98,10 +101,8 @@ class AutoTimer final { private: // We take in the current time so that we don't measure time to call // to or format() in the duration. - double logImpl(std::chrono::time_point now, StringPiece msg) { - double duration = - std::chrono::duration_cast>(now - start_) - .count(); + DoubleSeconds logImpl(std::chrono::time_point now, StringPiece msg) { + auto duration = now - start_; if (duration >= minTimeToLog_) { logger_(msg, duration); } @@ -111,7 +112,7 @@ class AutoTimer final { const std::string destructionMessage_; std::chrono::time_point start_ = Clock::now(); - double minTimeToLog_; + DoubleSeconds minTimeToLog_; Logger logger_; }; @@ -120,7 +121,8 @@ template < class Clock = std::chrono::high_resolution_clock> auto makeAutoTimer( std::string&& msg = "", - double minTimeToLog = 0.0, + const std::chrono::duration& minTimeToLog = + std::chrono::duration::zero(), Logger&& logger = Logger()) { return AutoTimer( std::move(msg), minTimeToLog, std::move(logger)); @@ -128,14 +130,16 @@ auto makeAutoTimer( template struct GoogleLogger final { - void operator()(StringPiece msg, double sec) const { + void operator()(StringPiece msg, const std::chrono::duration& sec) + const { if (msg.empty()) { return; } if (Style == GoogleLoggerStyle::PRETTY) { - LOG(INFO) << msg << " in " << prettyPrint(sec, PrettyType::PRETTY_TIME); + LOG(INFO) << msg << " in " + << prettyPrint(sec.count(), PrettyType::PRETTY_TIME); } else { - LOG(INFO) << msg << " in " << sec << " seconds"; + LOG(INFO) << msg << " in " << sec.count() << " seconds"; } } }; diff --git a/folly/experimental/test/AutoTimerTest.cpp b/folly/experimental/test/AutoTimerTest.cpp index 9fb47a3d..791092ea 100644 --- a/folly/experimental/test/AutoTimerTest.cpp +++ b/folly/experimental/test/AutoTimerTest.cpp @@ -21,9 +21,9 @@ using namespace folly; using namespace std; struct StubLogger { - void operator()(StringPiece msg, double sec) { + void operator()(StringPiece msg, std::chrono::duration sec) { m = msg.str(); - t = sec; + t = sec.count(); } static std::string m; static double t; @@ -44,15 +44,15 @@ struct StubClock { int StubClock::t = 0; TEST(TestAutoTimer, HandleBasicClosure) { - auto logger = [](StringPiece msg, double sec) { + auto logger = [](StringPiece msg, auto sec) { return StubLogger()(msg, sec); }; StubClock::t = 1; // Here decltype is needed. But since most users are expected to use this // method with the default clock, template specification won't be needed even // when they use a closure. See test case HandleRealTimerClosure - auto timer = - makeAutoTimer("", 0.0, std::move(logger)); + auto timer = makeAutoTimer( + "", std::chrono::duration::zero(), std::move(logger)); StubClock::t = 3; timer.log("foo"); ASSERT_EQ("foo", StubLogger::m); @@ -90,7 +90,9 @@ TEST(TestAutoTimer, HandleLogOnDestruct) { TEST(TestAutoTimer, HandleRealTimerClosure) { auto t = makeAutoTimer( - "Third message on destruction", 0.0, [](StringPiece msg, double sec) { + "Third message on destruction", + std::chrono::duration::zero(), + [](StringPiece msg, auto sec) { GoogleLogger()(msg, sec); }); t.log("First message"); @@ -105,10 +107,10 @@ TEST(TestAutoTimer, HandleRealTimer) { TEST(TestAutoTimer, HandleMinLogTime) { StubClock::t = 1; - AutoTimer timer("", 3); + AutoTimer timer("", std::chrono::duration(3)); StubClock::t = 3; // only 2 "seconds" have passed, so this shouldn't log StubLogger::t = 0; - ASSERT_EQ(2.0, timer.log("foo")); - ASSERT_EQ(0, StubLogger::t); + ASSERT_EQ(std::chrono::duration(2), timer.log("foo")); + ASSERT_EQ(std::chrono::duration::zero().count(), StubLogger::t); }