Reduce allocations when parsing times
Change-Id: Ife37d75fef81f5ecff14259f4567b2e16fcd97ab
Signed-off-by: Austin Schuh <austin.linux@gmail.com>
diff --git a/aos/time/BUILD b/aos/time/BUILD
index c0bd99d..04ae38f 100644
--- a/aos/time/BUILD
+++ b/aos/time/BUILD
@@ -8,7 +8,10 @@
],
visibility = ["//visibility:public"],
deps = select({
- "@platforms//os:linux": ["@com_github_google_glog//:glog"],
+ "@platforms//os:linux": [
+ "@com_github_google_glog//:glog",
+ "@com_google_absl//absl/strings",
+ ],
"//conditions:default": ["//motors/core"],
}),
)
diff --git a/aos/time/time.cc b/aos/time/time.cc
index 05510e9..4f39c36 100644
--- a/aos/time/time.cc
+++ b/aos/time/time.cc
@@ -9,6 +9,7 @@
#ifdef __linux__
+#include "absl/strings/numbers.h"
#include "glog/logging.h"
#else // __linux__
@@ -80,6 +81,7 @@
return stream;
}
+#ifdef __linux__
std::optional<monotonic_clock::time_point> monotonic_clock::FromString(
const std::string_view now) {
// This should undo the operator << above.
@@ -97,18 +99,28 @@
bool negative = now[0] == '-';
- std::string sec(
+ std::string_view sec(
now.substr(negative ? 1 : 0, now.size() - (negative ? 14 : 13)));
- std::string nsec(now.substr(now.size() - 12, 9));
+ std::string_view nsec(now.substr(now.size() - 12, 9));
if (!std::all_of(sec.begin(), sec.end(), ::isdigit) ||
!std::all_of(nsec.begin(), nsec.end(), ::isdigit)) {
return std::nullopt;
}
+ std::chrono::seconds::rep seconds_data;
+ if (!absl::SimpleAtoi(sec, &seconds_data)) {
+ return std::nullopt;
+ }
+
+ std::chrono::nanoseconds::rep nanoseconds_data;
+ if (!absl::SimpleAtoi(nsec, &nanoseconds_data)) {
+ return std::nullopt;
+ }
+
return monotonic_clock::time_point(
- std::chrono::seconds((negative ? -1 : 1) * atoll(sec.c_str())) +
- std::chrono::nanoseconds((negative ? -1 : 1) * atoll(nsec.c_str())));
+ std::chrono::seconds((negative ? -1 : 1) * seconds_data) +
+ std::chrono::nanoseconds((negative ? -1 : 1) * nanoseconds_data));
}
std::optional<realtime_clock::time_point> realtime_clock::FromString(
@@ -123,7 +135,7 @@
return std::nullopt;
}
- std::string nsec(now.substr(now.size() - 9, 9));
+ std::string_view nsec(now.substr(now.size() - 9, 9));
if (!std::all_of(nsec.begin(), nsec.end(), ::isdigit)) {
return std::nullopt;
@@ -139,10 +151,16 @@
time_t seconds = mktime(&tm);
+ std::chrono::nanoseconds::rep nanoseconds_data;
+ if (!absl::SimpleAtoi(nsec, &nanoseconds_data)) {
+ return std::nullopt;
+ }
+
return realtime_clock::time_point(
std::chrono::seconds(seconds) +
- std::chrono::nanoseconds(atoll(nsec.c_str())));
+ std::chrono::nanoseconds(nanoseconds_data));
}
+#endif
std::ostream &operator<<(std::ostream &stream,
const aos::realtime_clock::time_point &now) {
diff --git a/aos/time/time.h b/aos/time/time.h
index 52d763f..cd4ecda 100644
--- a/aos/time/time.h
+++ b/aos/time/time.h
@@ -26,8 +26,10 @@
// Converts the time string to a time_point if it is well formatted. This is
// designed to reverse operator <<.
+#ifdef __linux__
static std::optional<monotonic_clock::time_point> FromString(
const std::string_view now);
+#endif
// Returns the epoch (0).
static constexpr monotonic_clock::time_point epoch() {
@@ -56,8 +58,10 @@
// Converts the time string to a time_point if it is well formatted. This is
// designed to reverse operator <<.
+#ifdef __linux__
static std::optional<realtime_clock::time_point> FromString(
const std::string_view now);
+#endif
// Returns the epoch (0).
static constexpr realtime_clock::time_point epoch() {