aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow/core/lib
diff options
context:
space:
mode:
authorGravatar A. Unique TensorFlower <gardener@tensorflow.org>2016-09-06 13:55:35 -0800
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2016-09-06 15:02:22 -0700
commit6e369da8b4a8668169cdd6a93c8a069a5a4888c2 (patch)
tree28c522a7fceecef070588ccb9197566d365e7373 /tensorflow/core/lib
parent51a8d2e56a9af0d5501472c4f11cb03a9d6aba8c (diff)
Add new str_util::HumanReadableElapsedTime that formats a 'double seconds' value
using appropriate units based on the magnitude of the time interval, and add tests for this. Change: 132365945
Diffstat (limited to 'tensorflow/core/lib')
-rw-r--r--tensorflow/core/lib/strings/str_util.cc54
-rw-r--r--tensorflow/core/lib/strings/str_util.h9
-rw-r--r--tensorflow/core/lib/strings/str_util_test.cc19
3 files changed, 82 insertions, 0 deletions
diff --git a/tensorflow/core/lib/strings/str_util.cc b/tensorflow/core/lib/strings/str_util.cc
index 1c315655c1..8ae56b4906 100644
--- a/tensorflow/core/lib/strings/str_util.cc
+++ b/tensorflow/core/lib/strings/str_util.cc
@@ -18,6 +18,7 @@ limitations under the License.
#include <ctype.h>
#include <vector>
#include "tensorflow/core/lib/strings/numbers.h"
+#include "tensorflow/core/lib/strings/stringprintf.h"
namespace tensorflow {
namespace str_util {
@@ -334,5 +335,58 @@ bool SplitAndParseAsInts(StringPiece text, char delim,
return true;
}
+string HumanReadableElapsedTime(double seconds) {
+ string human_readable;
+
+ if (seconds < 0) {
+ human_readable = "-";
+ seconds = -seconds;
+ }
+
+ // Start with us and keep going up to years.
+ // The comparisons must account for rounding to prevent the format breaking
+ // the tested condition and returning, e.g., "1e+03 us" instead of "1 ms".
+ const double microseconds = seconds * 1.0e6;
+ if (microseconds < 999.5) {
+ strings::Appendf(&human_readable, "%0.3g us", microseconds);
+ return human_readable;
+ }
+ double milliseconds = seconds * 1e3;
+ if (milliseconds >= .995 && milliseconds < 1) {
+ // Round half to even in Appendf would convert this to 0.999 ms.
+ milliseconds = 1.0;
+ }
+ if (milliseconds < 999.5) {
+ strings::Appendf(&human_readable, "%0.3g ms", milliseconds);
+ return human_readable;
+ }
+ if (seconds < 60.0) {
+ strings::Appendf(&human_readable, "%0.3g s", seconds);
+ return human_readable;
+ }
+ seconds /= 60.0;
+ if (seconds < 60.0) {
+ strings::Appendf(&human_readable, "%0.3g min", seconds);
+ return human_readable;
+ }
+ seconds /= 60.0;
+ if (seconds < 24.0) {
+ strings::Appendf(&human_readable, "%0.3g h", seconds);
+ return human_readable;
+ }
+ seconds /= 24.0;
+ if (seconds < 30.0) {
+ strings::Appendf(&human_readable, "%0.3g days", seconds);
+ return human_readable;
+ }
+ if (seconds < 365.2425) {
+ strings::Appendf(&human_readable, "%0.3g months", seconds / 30.436875);
+ return human_readable;
+ }
+ seconds /= 365.2425;
+ strings::Appendf(&human_readable, "%0.3g years", seconds);
+ return human_readable;
+}
+
} // namespace str_util
} // namespace tensorflow
diff --git a/tensorflow/core/lib/strings/str_util.h b/tensorflow/core/lib/strings/str_util.h
index 4a519425d4..8198b7c541 100644
--- a/tensorflow/core/lib/strings/str_util.h
+++ b/tensorflow/core/lib/strings/str_util.h
@@ -80,6 +80,15 @@ string Uppercase(StringPiece s);
// set of characters that can be used as word boundaries.
void TitlecaseString(string* s, StringPiece delimiters);
+// Converts a time interval as double to a human readable
+// string. For example:
+// 0.001 -> "1 ms"
+// 10.0 -> "10 s"
+// 933120.0 -> "10.8 days"
+// 39420000.0 -> "1.25 years"
+// -10 -> "-10 s"
+string HumanReadableElapsedTime(double seconds);
+
// Join functionality
template <typename T>
string Join(const T& s, const char* sep);
diff --git a/tensorflow/core/lib/strings/str_util_test.cc b/tensorflow/core/lib/strings/str_util_test.cc
index a0494190fd..6481e5cfd7 100644
--- a/tensorflow/core/lib/strings/str_util_test.cc
+++ b/tensorflow/core/lib/strings/str_util_test.cc
@@ -287,4 +287,23 @@ TEST(TitlecaseString, Basic) {
ASSERT_EQ(s, "Dense");
}
+TEST(HumanReadableElapsedTime, Basic) {
+ EXPECT_EQ(str_util::HumanReadableElapsedTime(-10), "-10 s");
+ EXPECT_EQ(str_util::HumanReadableElapsedTime(-0.001), "-1 ms");
+ EXPECT_EQ(str_util::HumanReadableElapsedTime(-60.0), "-1 min");
+ EXPECT_EQ(str_util::HumanReadableElapsedTime(0.00000001), "0.01 us");
+ EXPECT_EQ(str_util::HumanReadableElapsedTime(0.0000012), "1.2 us");
+ EXPECT_EQ(str_util::HumanReadableElapsedTime(0.0012), "1.2 ms");
+ EXPECT_EQ(str_util::HumanReadableElapsedTime(0.12), "120 ms");
+ EXPECT_EQ(str_util::HumanReadableElapsedTime(1.12), "1.12 s");
+ EXPECT_EQ(str_util::HumanReadableElapsedTime(90.0), "1.5 min");
+ EXPECT_EQ(str_util::HumanReadableElapsedTime(600.0), "10 min");
+ EXPECT_EQ(str_util::HumanReadableElapsedTime(9000.0), "2.5 h");
+ EXPECT_EQ(str_util::HumanReadableElapsedTime(87480.0), "1.01 days");
+ EXPECT_EQ(str_util::HumanReadableElapsedTime(7776000.0), "2.96 months");
+ EXPECT_EQ(str_util::HumanReadableElapsedTime(78840000.0), "2.5 years");
+ EXPECT_EQ(str_util::HumanReadableElapsedTime(382386614.40), "12.1 years");
+ EXPECT_EQ(str_util::HumanReadableElapsedTime(DBL_MAX), "5.7e+300 years");
+}
+
} // namespace tensorflow