diff options
author | 2016-09-18 14:48:00 -0800 | |
---|---|---|
committer | 2016-09-18 16:02:38 -0700 | |
commit | 521caa5774d7be04e9682091a251d8bc8721008f (patch) | |
tree | 3896ee018f79cc7c0e00b7b99bc2e107ff116fcf | |
parent | 7767742e20b5480a5e95590a16254ab25566db99 (diff) |
Add strings::HumanReadableNum to tensorflow/core/lib/strings/numbers.h
Move HumanReadableElapsedTime from tensorflow/core/lib/strings/str_util.h
to tensorflow/core/lib/strings/numbers.h to match the other HumanReadable*
routines.
Change: 133533798
-rw-r--r-- | tensorflow/core/lib/strings/numbers.cc | 79 | ||||
-rw-r--r-- | tensorflow/core/lib/strings/numbers.h | 13 | ||||
-rw-r--r-- | tensorflow/core/lib/strings/numbers_test.cc | 31 | ||||
-rw-r--r-- | tensorflow/core/lib/strings/str_util.cc | 53 | ||||
-rw-r--r-- | tensorflow/core/lib/strings/str_util.h | 9 | ||||
-rw-r--r-- | tensorflow/core/lib/strings/str_util_test.cc | 19 |
6 files changed, 122 insertions, 82 deletions
diff --git a/tensorflow/core/lib/strings/numbers.cc b/tensorflow/core/lib/strings/numbers.cc index a3212451b4..de7bd30a47 100644 --- a/tensorflow/core/lib/strings/numbers.cc +++ b/tensorflow/core/lib/strings/numbers.cc @@ -1,5 +1,4 @@ /* Copyright 2015 The TensorFlow Authors. All Rights Reserved. - Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at @@ -23,6 +22,7 @@ limitations under the License. #include <cmath> #include <unordered_map> +#include "tensorflow/core/lib/strings/stringprintf.h" #include "tensorflow/core/platform/logging.h" #include "tensorflow/core/platform/macros.h" #include "tensorflow/core/platform/types.h" @@ -399,6 +399,30 @@ bool HexStringToUint64(const StringPiece& s, uint64* result) { return true; } +string HumanReadableNum(int64 value) { + string s; + if (value < 0) { + s += "-"; + value = -value; + } + if (value < 1000) { + Appendf(&s, "%lld", value); + } else if (value >= static_cast<int64>(1e15)) { + // Number bigger than 1E15; use that notation. + Appendf(&s, "%0.3G", static_cast<double>(value)); + } else { + static const char units[] = "kMBT"; + const char* unit = units; + while (value >= static_cast<int64>(1000000)) { + value /= static_cast<int64>(1000); + ++unit; + CHECK(unit < units + TF_ARRAYSIZE(units)); + } + Appendf(&s, "%.2f%c", value / 1000.0, *unit); + } + return s; +} + string HumanReadableNumBytes(int64 num_bytes) { if (num_bytes == kint64min) { // Special case for number with not representable negation. @@ -434,5 +458,58 @@ string HumanReadableNumBytes(int64 num_bytes) { return string(buf); } +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 strings } // namespace tensorflow diff --git a/tensorflow/core/lib/strings/numbers.h b/tensorflow/core/lib/strings/numbers.h index 2125bf884c..31b6abbac6 100644 --- a/tensorflow/core/lib/strings/numbers.h +++ b/tensorflow/core/lib/strings/numbers.h @@ -122,11 +122,24 @@ bool safe_strtof(const char* str, float* value); // Values may be rounded on over- and underflow. bool safe_strtod(const char* str, double* value); +// Converts from an int64 to a human readable string representing the +// same number, using decimal powers. e.g. 1200000 -> "1.20M". +string HumanReadableNum(int64 value); + // Converts from an int64 representing a number of bytes to a // human readable string representing the same number. // e.g. 12345678 -> "11.77MiB". string HumanReadableNumBytes(int64 num_bytes); +// 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); + } // namespace strings } // namespace tensorflow diff --git a/tensorflow/core/lib/strings/numbers_test.cc b/tensorflow/core/lib/strings/numbers_test.cc index 66f820762f..e15161de66 100644 --- a/tensorflow/core/lib/strings/numbers_test.cc +++ b/tensorflow/core/lib/strings/numbers_test.cc @@ -58,6 +58,18 @@ TEST(Uint64ToHexString, Ints) { EXPECT_FALSE(HexStringToUint64("0000000000000000xyz", &dummy)); } +TEST(HumanReadableNum, Basic) { + EXPECT_EQ(HumanReadableNum(823), "823"); + EXPECT_EQ(HumanReadableNum(1024), "1.02k"); + EXPECT_EQ(HumanReadableNum(4000), "4.00k"); + EXPECT_EQ(HumanReadableNum(999499), "999.50k"); + EXPECT_EQ(HumanReadableNum(1000000), "1.00M"); + EXPECT_EQ(HumanReadableNum(1048575), "1.05M"); + EXPECT_EQ(HumanReadableNum(1048576), "1.05M"); + EXPECT_EQ(HumanReadableNum(23956812342), "23.96B"); + EXPECT_EQ(HumanReadableNum(123456789012345678), "1.23E+17"); +} + TEST(HumanReadableNumBytes, Bytes) { EXPECT_EQ("0B", HumanReadableNumBytes(0)); EXPECT_EQ("4B", HumanReadableNumBytes(4)); @@ -85,6 +97,25 @@ TEST(HumanReadableNumBytes, Bytes) { EXPECT_EQ("-8E", HumanReadableNumBytes(kint64min)); } +TEST(HumanReadableElapsedTime, Basic) { + EXPECT_EQ(HumanReadableElapsedTime(-10), "-10 s"); + EXPECT_EQ(HumanReadableElapsedTime(-0.001), "-1 ms"); + EXPECT_EQ(HumanReadableElapsedTime(-60.0), "-1 min"); + EXPECT_EQ(HumanReadableElapsedTime(0.00000001), "0.01 us"); + EXPECT_EQ(HumanReadableElapsedTime(0.0000012), "1.2 us"); + EXPECT_EQ(HumanReadableElapsedTime(0.0012), "1.2 ms"); + EXPECT_EQ(HumanReadableElapsedTime(0.12), "120 ms"); + EXPECT_EQ(HumanReadableElapsedTime(1.12), "1.12 s"); + EXPECT_EQ(HumanReadableElapsedTime(90.0), "1.5 min"); + EXPECT_EQ(HumanReadableElapsedTime(600.0), "10 min"); + EXPECT_EQ(HumanReadableElapsedTime(9000.0), "2.5 h"); + EXPECT_EQ(HumanReadableElapsedTime(87480.0), "1.01 days"); + EXPECT_EQ(HumanReadableElapsedTime(7776000.0), "2.96 months"); + EXPECT_EQ(HumanReadableElapsedTime(78840000.0), "2.5 years"); + EXPECT_EQ(HumanReadableElapsedTime(382386614.40), "12.1 years"); + EXPECT_EQ(HumanReadableElapsedTime(DBL_MAX), "5.7e+300 years"); +} + TEST(safe_strto32, Int32s) { int32 result; diff --git a/tensorflow/core/lib/strings/str_util.cc b/tensorflow/core/lib/strings/str_util.cc index c3627d4286..6a794839f2 100644 --- a/tensorflow/core/lib/strings/str_util.cc +++ b/tensorflow/core/lib/strings/str_util.cc @@ -343,58 +343,5 @@ 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 5f42c2cfcd..288b599441 100644 --- a/tensorflow/core/lib/strings/str_util.h +++ b/tensorflow/core/lib/strings/str_util.h @@ -85,15 +85,6 @@ 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 b57089b857..091691c7b2 100644 --- a/tensorflow/core/lib/strings/str_util_test.cc +++ b/tensorflow/core/lib/strings/str_util_test.cc @@ -297,23 +297,4 @@ 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 |