Use absl::time

Replace WallTimeInSeconds with absl::Now and use
absl::Time and absl::Duration objects instead of doubles.

wall_time.h/cc -> event_logger.h/cc

Change-Id: I41279961368840fbdf6bb3456ffdbdf2f9bfb85b
diff --git a/internal/ceres/CMakeLists.txt b/internal/ceres/CMakeLists.txt
index 98d74cf..921ea9e 100644
--- a/internal/ceres/CMakeLists.txt
+++ b/internal/ceres/CMakeLists.txt
@@ -36,6 +36,7 @@
 set(Threads_DEPENDENCY "find_dependency (Threads)" PARENT_SCOPE)
 list(APPEND CERES_LIBRARY_PRIVATE_DEPENDENCIES  $<LINK_LIBRARY:WHOLE_ARCHIVE,absl::log_flags>)
 list(APPEND CERES_LIBRARY_PRIVATE_DEPENDENCIES absl::strings)
+list(APPEND CERES_LIBRARY_PRIVATE_DEPENDENCIES absl::time)
 
 list(APPEND CERES_LIBRARY_PUBLIC_DEPENDENCIES absl::log)
 list(APPEND CERES_LIBRARY_PUBLIC_DEPENDENCIES absl::check)
@@ -169,6 +170,7 @@
     eigensparse.cc
     evaluation_callback.cc
     evaluator.cc
+    event_logger.cc
     fake_bundle_adjustment_jacobian.cc
     file.cc
     first_order_function.cc
@@ -227,7 +229,6 @@
     trust_region_strategy.cc
     visibility.cc
     visibility_based_preconditioner.cc
-    wall_time.cc
 )
 
 set(CERES_LIBRARY_SOURCE
diff --git a/internal/ceres/cgnr_solver.cc b/internal/ceres/cgnr_solver.cc
index 06c19d6..4746006 100644
--- a/internal/ceres/cgnr_solver.cc
+++ b/internal/ceres/cgnr_solver.cc
@@ -39,10 +39,10 @@
 #include "ceres/conjugate_gradients_solver.h"
 #include "ceres/cuda_sparse_matrix.h"
 #include "ceres/cuda_vector.h"
+#include "ceres/event_logger.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/linear_solver.h"
 #include "ceres/subset_preconditioner.h"
-#include "ceres/wall_time.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/context_impl.cc b/internal/ceres/context_impl.cc
index be4aa29..88f0859 100644
--- a/internal/ceres/context_impl.cc
+++ b/internal/ceres/context_impl.cc
@@ -35,8 +35,8 @@
 #include "absl/log/check.h"
 #include "absl/log/log.h"
 #include "absl/strings/str_format.h"
+#include "ceres/event_logger.h"
 #include "ceres/internal/config.h"
-#include "ceres/wall_time.h"
 
 #ifndef CERES_NO_CUDA
 #include "cublas_v2.h"
diff --git a/internal/ceres/covariance_impl.cc b/internal/ceres/covariance_impl.cc
index c9c292f..bdbb590 100644
--- a/internal/ceres/covariance_impl.cc
+++ b/internal/ceres/covariance_impl.cc
@@ -48,6 +48,7 @@
 #include "ceres/compressed_row_sparse_matrix.h"
 #include "ceres/covariance.h"
 #include "ceres/crs_matrix.h"
+#include "ceres/event_logger.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/map_util.h"
 #include "ceres/parallel_for.h"
@@ -56,7 +57,6 @@
 #include "ceres/problem_impl.h"
 #include "ceres/residual_block.h"
 #include "ceres/suitesparse.h"
-#include "ceres/wall_time.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/cuda_sparse_matrix.cc b/internal/ceres/cuda_sparse_matrix.cc
index b55495b..9cb25d5 100644
--- a/internal/ceres/cuda_sparse_matrix.cc
+++ b/internal/ceres/cuda_sparse_matrix.cc
@@ -48,7 +48,6 @@
 #include "ceres/crs_matrix.h"
 #include "ceres/internal/export.h"
 #include "ceres/types.h"
-#include "ceres/wall_time.h"
 
 #ifndef CERES_NO_CUDA
 
diff --git a/internal/ceres/dense_normal_cholesky_solver.cc b/internal/ceres/dense_normal_cholesky_solver.cc
index f6d5e5a..f295910 100644
--- a/internal/ceres/dense_normal_cholesky_solver.cc
+++ b/internal/ceres/dense_normal_cholesky_solver.cc
@@ -34,10 +34,10 @@
 
 #include "Eigen/Dense"
 #include "ceres/dense_sparse_matrix.h"
+#include "ceres/event_logger.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/linear_solver.h"
 #include "ceres/types.h"
-#include "ceres/wall_time.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/dense_qr_solver.cc b/internal/ceres/dense_qr_solver.cc
index 92652b4..9466689 100644
--- a/internal/ceres/dense_qr_solver.cc
+++ b/internal/ceres/dense_qr_solver.cc
@@ -35,10 +35,10 @@
 #include "Eigen/Dense"
 #include "ceres/dense_qr.h"
 #include "ceres/dense_sparse_matrix.h"
+#include "ceres/event_logger.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/linear_solver.h"
 #include "ceres/types.h"
-#include "ceres/wall_time.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/dynamic_sparse_normal_cholesky_solver.cc b/internal/ceres/dynamic_sparse_normal_cholesky_solver.cc
index 0d147c4..e66083f 100644
--- a/internal/ceres/dynamic_sparse_normal_cholesky_solver.cc
+++ b/internal/ceres/dynamic_sparse_normal_cholesky_solver.cc
@@ -40,13 +40,13 @@
 #include "Eigen/SparseCore"
 #include "absl/log/log.h"
 #include "ceres/compressed_row_sparse_matrix.h"
+#include "ceres/event_logger.h"
 #include "ceres/internal/config.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/linear_solver.h"
 #include "ceres/suitesparse.h"
 #include "ceres/triplet_sparse_matrix.h"
 #include "ceres/types.h"
-#include "ceres/wall_time.h"
 #include "cuda_sparse_cholesky.h"
 
 #ifdef CERES_USE_EIGEN_SPARSE
diff --git a/internal/ceres/wall_time.cc b/internal/ceres/event_logger.cc
similarity index 70%
rename from internal/ceres/wall_time.cc
rename to internal/ceres/event_logger.cc
index fa07470..5fd010b 100644
--- a/internal/ceres/wall_time.cc
+++ b/internal/ceres/event_logger.cc
@@ -1,5 +1,5 @@
 // Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2023 Google Inc. All rights reserved.
+// Copyright 2024 Google Inc. All rights reserved.
 // http://ceres-solver.org/
 //
 // Redistribution and use in source and binary forms, with or without
@@ -28,43 +28,22 @@
 //
 // Author: strandmark@google.com (Petter Strandmark)
 
-#include "ceres/wall_time.h"
-
-#include <ctime>
+#include "ceres/event_logger.h"
 
 #include "absl/log/log.h"
 #include "absl/strings/str_format.h"
+#include "absl/time/clock.h"
+#include "absl/time/time.h"
 #include "ceres/internal/config.h"
 
-#ifdef _WIN32
-#include <windows.h>
-#else
-#include <sys/time.h>
-#endif
-
 namespace ceres::internal {
 
-double WallTimeInSeconds() {
-#ifdef _WIN32
-  LARGE_INTEGER count;
-  LARGE_INTEGER frequency;
-  QueryPerformanceCounter(&count);
-  QueryPerformanceFrequency(&frequency);
-  return static_cast<double>(count.QuadPart) /
-         static_cast<double>(frequency.QuadPart);
-#else
-  timeval time_val;
-  gettimeofday(&time_val, nullptr);
-  return (time_val.tv_sec + time_val.tv_usec * 1e-6);
-#endif
-}
-
-EventLogger::EventLogger(const std::string& logger_name) {
+EventLogger::EventLogger(const std::string& logger_name)
+    : start_time_(absl::Now()) {
   if (!VLOG_IS_ON(3)) {
     return;
   }
 
-  start_time_ = WallTimeInSeconds();
   last_event_time_ = start_time_;
   events_ = absl::StrFormat(
       "\n%s\n                                        Delta   Cumulative\n",
@@ -84,16 +63,13 @@
     return;
   }
 
-  const double current_time = WallTimeInSeconds();
-  const double relative_time_delta = current_time - last_event_time_;
-  const double absolute_time_delta = current_time - start_time_;
-  last_event_time_ = current_time;
-
+  const absl::Time now = absl::Now();
   absl::StrAppendFormat(&events_,
                         "  %30s : %10.5f   %10.5f\n",
                         event_name,
-                        relative_time_delta,
-                        absolute_time_delta);
+                        absl::ToDoubleSeconds(now - last_event_time_),
+                        absl::ToDoubleSeconds(now - start_time_));
+  last_event_time_ = now;
 }
 
 }  // namespace ceres::internal
diff --git a/internal/ceres/wall_time.h b/internal/ceres/event_logger.h
similarity index 86%
rename from internal/ceres/wall_time.h
rename to internal/ceres/event_logger.h
index 8878f9b..d01119f 100644
--- a/internal/ceres/wall_time.h
+++ b/internal/ceres/event_logger.h
@@ -1,5 +1,5 @@
 // Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2023 Google Inc. All rights reserved.
+// Copyright 2024 Google Inc. All rights reserved.
 // http://ceres-solver.org/
 //
 // Redistribution and use in source and binary forms, with or without
@@ -28,21 +28,17 @@
 //
 // Author: strandmark@google.com (Petter Strandmark)
 
-#ifndef CERES_INTERNAL_WALL_TIME_H_
-#define CERES_INTERNAL_WALL_TIME_H_
+#ifndef CERES_INTERNAL_EVENT_LOGGER_H_
+#define CERES_INTERNAL_EVENT_LOGGER_H_
 
-#include <map>
 #include <string>
 
+#include "absl/time/time.h"
 #include "ceres/internal/disable_warnings.h"
 #include "ceres/internal/export.h"
 
 namespace ceres::internal {
 
-// Returns time, in seconds, from some arbitrary starting point. On unixes,
-// gettimeofday is used. The granularity is microseconds.
-CERES_NO_EXPORT double WallTimeInSeconds();
-
 // Log a series of events, recording for each event the time elapsed
 // since the last event and since the creation of the object.
 //
@@ -74,8 +70,8 @@
   void AddEvent(const std::string& event_name);
 
  private:
-  double start_time_;
-  double last_event_time_;
+  const absl::Time start_time_;
+  absl::Time last_event_time_;
   std::string events_;
 };
 
@@ -83,4 +79,4 @@
 
 #include "ceres/internal/reenable_warnings.h"
 
-#endif  // CERES_INTERNAL_WALL_TIME_H_
+#endif  // CERES_INTERNAL_EVENT_LOGGER_H_
diff --git a/internal/ceres/execution_summary.h b/internal/ceres/execution_summary.h
index accc5e4..15eb7b3 100644
--- a/internal/ceres/execution_summary.h
+++ b/internal/ceres/execution_summary.h
@@ -36,14 +36,15 @@
 #include <string>
 #include <utility>
 
+#include "absl/time/clock.h"
+#include "absl/time/time.h"
 #include "ceres/internal/export.h"
-#include "ceres/wall_time.h"
 
 namespace ceres::internal {
 
 struct CallStatistics {
   CallStatistics() = default;
-  double time{0.};
+  absl::Duration time = absl::ZeroDuration();
   int calls{0};
 };
 
@@ -51,10 +52,10 @@
 // execution.
 class ExecutionSummary {
  public:
-  void IncrementTimeBy(const std::string& name, const double value) {
+  void IncrementTimeBy(const std::string& name, absl::Duration delta) {
     std::lock_guard<std::mutex> l(mutex_);
     CallStatistics& call_stats = statistics_[name];
-    call_stats.time += value;
+    call_stats.time += delta;
     ++call_stats.calls;
   }
 
@@ -70,16 +71,14 @@
 class ScopedExecutionTimer {
  public:
   ScopedExecutionTimer(std::string name, ExecutionSummary* summary)
-      : start_time_(WallTimeInSeconds()),
-        name_(std::move(name)),
-        summary_(summary) {}
+      : start_time_(absl::Now()), name_(std::move(name)), summary_(summary) {}
 
   ~ScopedExecutionTimer() {
-    summary_->IncrementTimeBy(name_, WallTimeInSeconds() - start_time_);
+    summary_->IncrementTimeBy(name_, absl::Now() - start_time_);
   }
 
  private:
-  const double start_time_;
+  absl::Time start_time_;
   const std::string name_;
   ExecutionSummary* summary_;
 };
diff --git a/internal/ceres/gradient_problem_evaluator.h b/internal/ceres/gradient_problem_evaluator.h
index 8b03015..d272f04 100644
--- a/internal/ceres/gradient_problem_evaluator.h
+++ b/internal/ceres/gradient_problem_evaluator.h
@@ -42,7 +42,6 @@
 #include "ceres/internal/disable_warnings.h"
 #include "ceres/internal/export.h"
 #include "ceres/sparse_matrix.h"
-#include "ceres/wall_time.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/gradient_problem_solver.cc b/internal/ceres/gradient_problem_solver.cc
index 535f4c2..02038da 100644
--- a/internal/ceres/gradient_problem_solver.cc
+++ b/internal/ceres/gradient_problem_solver.cc
@@ -38,6 +38,7 @@
 #include "absl/log/log.h"
 #include "absl/strings/str_cat.h"
 #include "absl/strings/str_format.h"
+#include "absl/time/time.h"
 #include "ceres/callbacks.h"
 #include "ceres/gradient_problem.h"
 #include "ceres/gradient_problem_evaluator.h"
@@ -48,7 +49,6 @@
 #include "ceres/solver.h"
 #include "ceres/solver_utils.h"
 #include "ceres/types.h"
-#include "ceres/wall_time.h"
 
 namespace ceres {
 namespace {
@@ -105,9 +105,8 @@
   using internal::LoggingCallback;
   using internal::Minimizer;
   using internal::SetSummaryFinalCost;
-  using internal::WallTimeInSeconds;
 
-  double start_time = WallTimeInSeconds();
+  const absl::Time start_time = absl::Now();
 
   CHECK(summary != nullptr);
   *summary = Summary();
@@ -186,18 +185,21 @@
   {
     const CallStatistics& call_stats = FindWithDefault(
         evaluator_statistics, "Evaluator::Residual", CallStatistics());
-    summary->cost_evaluation_time_in_seconds = call_stats.time;
+    summary->cost_evaluation_time_in_seconds =
+        absl::ToDoubleSeconds(call_stats.time);
     summary->num_cost_evaluations = call_stats.calls;
   }
 
   {
     const CallStatistics& call_stats = FindWithDefault(
         evaluator_statistics, "Evaluator::Jacobian", CallStatistics());
-    summary->gradient_evaluation_time_in_seconds = call_stats.time;
+    summary->gradient_evaluation_time_in_seconds =
+        absl::ToDoubleSeconds(call_stats.time);
     summary->num_gradient_evaluations = call_stats.calls;
   }
 
-  summary->total_time_in_seconds = WallTimeInSeconds() - start_time;
+  summary->total_time_in_seconds =
+      absl::ToDoubleSeconds(absl::Now() - start_time);
 }
 
 bool GradientProblemSolver::Summary::IsSolutionUsable() const {
diff --git a/internal/ceres/graph_algorithms.h b/internal/ceres/graph_algorithms.h
index 3019f0b..60520d5 100644
--- a/internal/ceres/graph_algorithms.h
+++ b/internal/ceres/graph_algorithms.h
@@ -43,7 +43,6 @@
 #include "absl/log/check.h"
 #include "ceres/graph.h"
 #include "ceres/internal/export.h"
-#include "ceres/wall_time.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/iterative_schur_complement_solver.cc b/internal/ceres/iterative_schur_complement_solver.cc
index 23318bb..e467841 100644
--- a/internal/ceres/iterative_schur_complement_solver.cc
+++ b/internal/ceres/iterative_schur_complement_solver.cc
@@ -42,6 +42,7 @@
 #include "ceres/block_structure.h"
 #include "ceres/conjugate_gradients_solver.h"
 #include "ceres/detect_structure.h"
+#include "ceres/event_logger.h"
 #include "ceres/implicit_schur_complement.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/linear_solver.h"
@@ -51,7 +52,6 @@
 #include "ceres/triplet_sparse_matrix.h"
 #include "ceres/types.h"
 #include "ceres/visibility_based_preconditioner.h"
-#include "ceres/wall_time.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/line_search.cc b/internal/ceres/line_search.cc
index 644e26e..9b6b71a 100644
--- a/internal/ceres/line_search.cc
+++ b/internal/ceres/line_search.cc
@@ -48,7 +48,6 @@
 #include "ceres/internal/eigen.h"
 #include "ceres/map_util.h"
 #include "ceres/polynomial.h"
-#include "ceres/wall_time.h"
 
 namespace ceres::internal {
 
@@ -91,9 +90,7 @@
     : evaluator_(evaluator),
       position_(evaluator->NumParameters()),
       direction_(evaluator->NumEffectiveParameters()),
-      scaled_direction_(evaluator->NumEffectiveParameters()),
-      initial_evaluator_residual_time_in_seconds(0.0),
-      initial_evaluator_jacobian_time_in_seconds(0.0) {}
+      scaled_direction_(evaluator->NumEffectiveParameters()) {}
 
 void LineSearchFunction::Init(const Vector& position, const Vector& direction) {
   position_ = position;
@@ -152,57 +149,56 @@
   const std::map<std::string, CallStatistics> evaluator_statistics =
       evaluator_->Statistics();
 
-  initial_evaluator_residual_time_in_seconds =
+  initial_evaluator_residual_time =
       FindWithDefault(
           evaluator_statistics, "Evaluator::Residual", CallStatistics())
           .time;
-  initial_evaluator_jacobian_time_in_seconds =
+  initial_evaluator_jacobian_time =
       FindWithDefault(
           evaluator_statistics, "Evaluator::Jacobian", CallStatistics())
           .time;
 }
 
 void LineSearchFunction::TimeStatistics(
-    double* cost_evaluation_time_in_seconds,
-    double* gradient_evaluation_time_in_seconds) const {
+    absl::Duration* cost_evaluation_time,
+    absl::Duration* gradient_evaluation_time) const {
   const std::map<std::string, CallStatistics> evaluator_time_statistics =
       evaluator_->Statistics();
-  *cost_evaluation_time_in_seconds =
+  *cost_evaluation_time =
       FindWithDefault(
           evaluator_time_statistics, "Evaluator::Residual", CallStatistics())
           .time -
-      initial_evaluator_residual_time_in_seconds;
+      initial_evaluator_residual_time;
   // Strictly speaking this will slightly underestimate the time spent
   // evaluating the gradient of the line search univariate cost function as it
   // does not count the time spent performing the dot product with the direction
   // vector.  However, this will typically be small by comparison, and also
   // allows direct subtraction of the timing information from the totals for
   // the evaluator returned in the solver summary.
-  *gradient_evaluation_time_in_seconds =
+  *gradient_evaluation_time =
       FindWithDefault(
           evaluator_time_statistics, "Evaluator::Jacobian", CallStatistics())
           .time -
-      initial_evaluator_jacobian_time_in_seconds;
+      initial_evaluator_jacobian_time;
 }
 
 void LineSearch::Search(double step_size_estimate,
                         double initial_cost,
                         double initial_gradient,
                         Summary* summary) const {
-  const double start_time = WallTimeInSeconds();
+  const absl::Time start_time = absl::Now();
   CHECK(summary != nullptr);
   *summary = LineSearch::Summary();
 
-  summary->cost_evaluation_time_in_seconds = 0.0;
-  summary->gradient_evaluation_time_in_seconds = 0.0;
-  summary->polynomial_minimization_time_in_seconds = 0.0;
+  summary->cost_evaluation_time = absl::ZeroDuration();
+  summary->gradient_evaluation_time = absl::ZeroDuration();
+  summary->polynomial_minimization_time = absl::ZeroDuration();
   options().function->ResetTimeStatistics();
   this->DoSearch(step_size_estimate, initial_cost, initial_gradient, summary);
-  options().function->TimeStatistics(
-      &summary->cost_evaluation_time_in_seconds,
-      &summary->gradient_evaluation_time_in_seconds);
+  options().function->TimeStatistics(&summary->cost_evaluation_time,
+                                     &summary->gradient_evaluation_time);
 
-  summary->total_time_in_seconds = WallTimeInSeconds() - start_time;
+  summary->total_time = absl::Now() - start_time;
 }
 
 // Returns step_size \in [min_step_size, max_step_size] which minimizes the
@@ -329,7 +325,7 @@
       return;
     }
 
-    const double polynomial_minimization_start_time = WallTimeInSeconds();
+    const absl::Time polynomial_minimization_start_time = absl::Now();
     const double step_size = this->InterpolatingPolynomialMinimizingStepSize(
         options().interpolation_type,
         initial_position,
@@ -337,8 +333,8 @@
         current,
         (options().max_step_contraction * current.x),
         (options().min_step_contraction * current.x));
-    summary->polynomial_minimization_time_in_seconds +=
-        (WallTimeInSeconds() - polynomial_minimization_start_time);
+    summary->polynomial_minimization_time +=
+        (absl::Now() - polynomial_minimization_start_time);
 
     if (step_size * descent_direction_max_norm < options().min_step_size) {
       summary->error = absl::StrFormat(
@@ -650,7 +646,7 @@
     const FunctionSample unused_previous;
     DCHECK(!unused_previous.value_is_valid);
     // Contracts step size if f(current) is not valid.
-    const double polynomial_minimization_start_time = WallTimeInSeconds();
+    const absl::Time polynomial_minimization_start_time = absl::Now();
     const double step_size = this->InterpolatingPolynomialMinimizingStepSize(
         options().interpolation_type,
         previous,
@@ -658,8 +654,8 @@
         current,
         min_step_size,
         max_step_size);
-    summary->polynomial_minimization_time_in_seconds +=
-        (WallTimeInSeconds() - polynomial_minimization_start_time);
+    summary->polynomial_minimization_time +=
+        (absl::Now() - polynomial_minimization_start_time);
     if (step_size * descent_direction_max_norm < options().min_step_size) {
       summary->error = absl::StrFormat(
           "Line search failed: step_size too small: %.5e "
@@ -804,7 +800,7 @@
     // value that will therefore be ignored.
     const FunctionSample unused_previous;
     DCHECK(!unused_previous.value_is_valid);
-    const double polynomial_minimization_start_time = WallTimeInSeconds();
+    const absl::Time polynomial_minimization_start_time = absl::Now();
     const double step_size = this->InterpolatingPolynomialMinimizingStepSize(
         options().interpolation_type,
         lower_bound_step,
@@ -812,8 +808,8 @@
         upper_bound_step,
         lower_bound_step.x,
         upper_bound_step.x);
-    summary->polynomial_minimization_time_in_seconds +=
-        (WallTimeInSeconds() - polynomial_minimization_start_time);
+    summary->polynomial_minimization_time +=
+        (absl::Now() - polynomial_minimization_start_time);
     // No check on magnitude of step size being too small here as it is
     // lower-bounded by the initial bracket start point, which was valid.
     //
diff --git a/internal/ceres/line_search.h b/internal/ceres/line_search.h
index acf85c0..cbe6396 100644
--- a/internal/ceres/line_search.h
+++ b/internal/ceres/line_search.h
@@ -37,6 +37,7 @@
 #include <string>
 #include <vector>
 
+#include "absl/time/time.h"
 #include "ceres/function_sample.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/internal/export.h"
@@ -149,14 +150,14 @@
     int num_iterations = 0;
     // Cumulative time spent evaluating the value of the cost function across
     // all iterations.
-    double cost_evaluation_time_in_seconds = 0.0;
+    absl::Duration cost_evaluation_time = absl::ZeroDuration();
     // Cumulative time spent evaluating the gradient of the cost function across
     // all iterations.
-    double gradient_evaluation_time_in_seconds = 0.0;
+    absl::Duration gradient_evaluation_time = absl::ZeroDuration();
     // Cumulative time spent minimizing the interpolating polynomial to compute
     // the next candidate step size across all iterations.
-    double polynomial_minimization_time_in_seconds = 0.0;
-    double total_time_in_seconds = 0.0;
+    absl::Duration polynomial_minimization_time = absl::ZeroDuration();
+    absl::Duration total_time = absl::ZeroDuration();
     std::string error;
   };
 
@@ -232,8 +233,8 @@
 
   // Resets to now, the start point for the results from TimeStatistics().
   void ResetTimeStatistics();
-  void TimeStatistics(double* cost_evaluation_time_in_seconds,
-                      double* gradient_evaluation_time_in_seconds) const;
+  void TimeStatistics(absl::Duration* cost_evaluation_time,
+                      absl::Duration* gradient_evaluation_time) const;
   const Vector& position() const { return position_; }
   const Vector& direction() const { return direction_; }
 
@@ -249,8 +250,8 @@
   // minimizer), hence we need to save the initial evaluation durations for the
   // value & gradient to accurately determine the duration of the evaluations
   // we invoked.  These are reset by a call to ResetTimeStatistics().
-  double initial_evaluator_residual_time_in_seconds;
-  double initial_evaluator_jacobian_time_in_seconds;
+  absl::Duration initial_evaluator_residual_time = absl::ZeroDuration();
+  absl::Duration initial_evaluator_jacobian_time = absl::ZeroDuration();
 };
 
 // Backtracking and interpolation based Armijo line search. This
diff --git a/internal/ceres/line_search_minimizer.cc b/internal/ceres/line_search_minimizer.cc
index 97e5f3c..756a2ae 100644
--- a/internal/ceres/line_search_minimizer.cc
+++ b/internal/ceres/line_search_minimizer.cc
@@ -58,7 +58,6 @@
 #include "ceres/line_search.h"
 #include "ceres/line_search_direction.h"
 #include "ceres/types.h"
-#include "ceres/wall_time.h"
 
 namespace ceres::internal {
 namespace {
@@ -87,8 +86,8 @@
                                    double* parameters,
                                    Solver::Summary* summary) {
   const bool is_not_silent = !options.is_silent;
-  double start_time = WallTimeInSeconds();
-  double iteration_start_time = start_time;
+  const absl::Time start_time = absl::Now();
+  absl::Time iteration_start_time = start_time;
 
   CHECK(options.evaluator != nullptr);
   Evaluator* evaluator = options.evaluator.get();
@@ -157,10 +156,12 @@
     return;
   }
 
+  absl::Time now = absl::Now();
   iteration_summary.iteration_time_in_seconds =
-      WallTimeInSeconds() - iteration_start_time;
+      absl::ToDoubleSeconds(now - iteration_start_time);
   iteration_summary.cumulative_time_in_seconds =
-      WallTimeInSeconds() - start_time + summary->preprocessor_time_in_seconds;
+      absl::ToDoubleSeconds(now - start_time) +
+      summary->preprocessor_time_in_seconds;
   summary->iterations.push_back(iteration_summary);
 
   LineSearchDirection::Options line_search_direction_options;
@@ -213,7 +214,7 @@
       break;
     }
 
-    iteration_start_time = WallTimeInSeconds();
+    iteration_start_time = absl::Now();
     if (iteration_summary.iteration >= options.max_num_iterations) {
       summary->message = "Maximum number of iterations reached.";
       summary->termination_type = NO_CONVERGENCE;
@@ -223,8 +224,9 @@
       break;
     }
 
-    const double total_solver_time = iteration_start_time - start_time +
-                                     summary->preprocessor_time_in_seconds;
+    const double total_solver_time =
+        absl::ToDoubleSeconds(iteration_start_time - start_time) +
+        summary->preprocessor_time_in_seconds;
     if (total_solver_time >= options.max_solver_time_in_seconds) {
       summary->message = "Maximum solver time reached.";
       summary->termination_type = NO_CONVERGENCE;
@@ -345,7 +347,7 @@
     current_state.step_size = optimal_point.x;
     previous_state = current_state;
     iteration_summary.step_solver_time_in_seconds =
-        WallTimeInSeconds() - iteration_start_time;
+        absl::ToDoubleSeconds(absl::Now() - iteration_start_time);
 
     if (optimal_point.vector_gradient_is_valid) {
       current_state.cost = optimal_point.value;
@@ -402,10 +404,11 @@
         line_search_summary.num_gradient_evaluations;
     iteration_summary.line_search_iterations =
         line_search_summary.num_iterations;
+    const absl::Time now = absl::Now();
     iteration_summary.iteration_time_in_seconds =
-        WallTimeInSeconds() - iteration_start_time;
+        absl::ToDoubleSeconds(now - iteration_start_time);
     iteration_summary.cumulative_time_in_seconds =
-        WallTimeInSeconds() - start_time +
+        absl::ToDoubleSeconds(now - start_time) +
         summary->preprocessor_time_in_seconds;
     summary->iterations.push_back(iteration_summary);
 
@@ -417,13 +420,13 @@
     // minimization.
     summary->num_line_search_steps += line_search_summary.num_iterations;
     summary->line_search_cost_evaluation_time_in_seconds +=
-        line_search_summary.cost_evaluation_time_in_seconds;
+        absl::ToDoubleSeconds(line_search_summary.cost_evaluation_time);
     summary->line_search_gradient_evaluation_time_in_seconds +=
-        line_search_summary.gradient_evaluation_time_in_seconds;
+        absl::ToDoubleSeconds(line_search_summary.gradient_evaluation_time);
     summary->line_search_polynomial_minimization_time_in_seconds +=
-        line_search_summary.polynomial_minimization_time_in_seconds;
+        absl::ToDoubleSeconds(line_search_summary.polynomial_minimization_time);
     summary->line_search_total_time_in_seconds +=
-        line_search_summary.total_time_in_seconds;
+        absl::ToDoubleSeconds(line_search_summary.total_time);
     ++summary->num_successful_steps;
 
     const double step_size_tolerance =
diff --git a/internal/ceres/line_search_preprocessor.cc b/internal/ceres/line_search_preprocessor.cc
index 1107f24..4ba3a9a 100644
--- a/internal/ceres/line_search_preprocessor.cc
+++ b/internal/ceres/line_search_preprocessor.cc
@@ -40,7 +40,6 @@
 #include "ceres/minimizer.h"
 #include "ceres/problem_impl.h"
 #include "ceres/program.h"
-#include "ceres/wall_time.h"
 
 namespace ceres::internal {
 namespace {
diff --git a/internal/ceres/parameter_block_ordering.cc b/internal/ceres/parameter_block_ordering.cc
index 5bac2fd..68dfb05 100644
--- a/internal/ceres/parameter_block_ordering.cc
+++ b/internal/ceres/parameter_block_ordering.cc
@@ -37,13 +37,13 @@
 #include <vector>
 
 #include "absl/log/check.h"
+#include "ceres/event_logger.h"
 #include "ceres/graph.h"
 #include "ceres/graph_algorithms.h"
 #include "ceres/map_util.h"
 #include "ceres/parameter_block.h"
 #include "ceres/program.h"
 #include "ceres/residual_block.h"
-#include "ceres/wall_time.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/schur_complement_solver.cc b/internal/ceres/schur_complement_solver.cc
index c62633c..ce0af45 100644
--- a/internal/ceres/schur_complement_solver.cc
+++ b/internal/ceres/schur_complement_solver.cc
@@ -47,12 +47,12 @@
 #include "ceres/block_structure.h"
 #include "ceres/conjugate_gradients_solver.h"
 #include "ceres/detect_structure.h"
+#include "ceres/event_logger.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/linear_solver.h"
 #include "ceres/sparse_cholesky.h"
 #include "ceres/triplet_sparse_matrix.h"
 #include "ceres/types.h"
-#include "ceres/wall_time.h"
 
 namespace ceres::internal {
 namespace {
diff --git a/internal/ceres/solver.cc b/internal/ceres/solver.cc
index 9ebee82..bb82e6d 100644
--- a/internal/ceres/solver.cc
+++ b/internal/ceres/solver.cc
@@ -42,6 +42,8 @@
 #include "absl/log/log.h"
 #include "absl/strings/str_cat.h"
 #include "absl/strings/str_format.h"
+#include "absl/time/clock.h"
+#include "absl/time/time.h"
 #include "ceres/casts.h"
 #include "ceres/context.h"
 #include "ceres/context_impl.h"
@@ -59,7 +61,6 @@
 #include "ceres/solver_utils.h"
 #include "ceres/suitesparse.h"
 #include "ceres/types.h"
-#include "ceres/wall_time.h"
 
 namespace ceres {
 namespace {
@@ -612,14 +613,16 @@
       const CallStatistics& call_stats = FindWithDefault(
           evaluator_statistics, "Evaluator::Residual", CallStatistics());
 
-      summary->residual_evaluation_time_in_seconds = call_stats.time;
+      summary->residual_evaluation_time_in_seconds =
+          absl::ToDoubleSeconds(call_stats.time);
       summary->num_residual_evaluations = call_stats.calls;
     }
     {
       const CallStatistics& call_stats = FindWithDefault(
           evaluator_statistics, "Evaluator::Jacobian", CallStatistics());
 
-      summary->jacobian_evaluation_time_in_seconds = call_stats.time;
+      summary->jacobian_evaluation_time_in_seconds =
+          absl::ToDoubleSeconds(call_stats.time);
       summary->num_jacobian_evaluations = call_stats.calls;
     }
   }
@@ -633,7 +636,8 @@
     const CallStatistics& call_stats = FindWithDefault(
         linear_solver_statistics, "LinearSolver::Solve", CallStatistics());
     summary->num_linear_solves = call_stats.calls;
-    summary->linear_solver_time_in_seconds = call_stats.time;
+    summary->linear_solver_time_in_seconds =
+        absl::ToDoubleSeconds(call_stats.time);
   }
 }
 
@@ -732,12 +736,11 @@
   using internal::Preprocessor;
   using internal::ProblemImpl;
   using internal::Program;
-  using internal::WallTimeInSeconds;
 
   CHECK(problem != nullptr);
   CHECK(summary != nullptr);
 
-  double start_time = WallTimeInSeconds();
+  const absl::Time start_time = absl::Now();
   *summary = Summary();
   if (!options.IsValid(&summary->message)) {
     LOG(ERROR) << "Terminating: " << summary->message;
@@ -814,18 +817,19 @@
   }
 
   summary->fixed_cost = pp.fixed_cost;
-  summary->preprocessor_time_in_seconds = WallTimeInSeconds() - start_time;
+  summary->preprocessor_time_in_seconds =
+      absl::ToDoubleSeconds(absl::Now() - start_time);
 
   if (status) {
-    const double minimizer_start_time = WallTimeInSeconds();
+    const absl::Time minimizer_start_time = absl::Now();
     Minimize(&pp, summary);
     summary->minimizer_time_in_seconds =
-        WallTimeInSeconds() - minimizer_start_time;
+        absl::ToDoubleSeconds(absl::Now() - minimizer_start_time);
   } else {
     summary->message = pp.error;
   }
 
-  const double postprocessor_start_time = WallTimeInSeconds();
+  const absl::Time postprocessor_start_time = absl::Now();
   problem_impl = problem->mutable_impl();
   program = problem_impl->mutable_program();
   // On exit, ensure that the parameter blocks again point at the user
@@ -835,7 +839,7 @@
   program->SetParameterOffsetsAndIndex();
   PostSolveSummarize(pp, summary);
   summary->postprocessor_time_in_seconds =
-      WallTimeInSeconds() - postprocessor_start_time;
+      absl::ToDoubleSeconds(absl::Now() - postprocessor_start_time);
 
   // If the gradient checker reported an error, we want to report FAILURE
   // instead of USER_FAILURE and provide the error log.
@@ -844,7 +848,8 @@
     summary->message = gradient_checking_callback.error_log();
   }
 
-  summary->total_time_in_seconds = WallTimeInSeconds() - start_time;
+  summary->total_time_in_seconds =
+      absl::ToDoubleSeconds(absl::Now() - start_time);
 }
 
 void Solve(const Solver::Options& options,
diff --git a/internal/ceres/sparse_normal_cholesky_solver.cc b/internal/ceres/sparse_normal_cholesky_solver.cc
index 5746509..78e4a6b 100644
--- a/internal/ceres/sparse_normal_cholesky_solver.cc
+++ b/internal/ceres/sparse_normal_cholesky_solver.cc
@@ -36,6 +36,7 @@
 #include <memory>
 
 #include "ceres/block_sparse_matrix.h"
+#include "ceres/event_logger.h"
 #include "ceres/inner_product_computer.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/iterative_refiner.h"
@@ -43,7 +44,6 @@
 #include "ceres/sparse_cholesky.h"
 #include "ceres/triplet_sparse_matrix.h"
 #include "ceres/types.h"
-#include "ceres/wall_time.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/trust_region_minimizer.cc b/internal/ceres/trust_region_minimizer.cc
index 971fc5b..3cbecbd 100644
--- a/internal/ceres/trust_region_minimizer.cc
+++ b/internal/ceres/trust_region_minimizer.cc
@@ -51,7 +51,6 @@
 #include "ceres/line_search.h"
 #include "ceres/parallel_for.h"
 #include "ceres/types.h"
-#include "ceres/wall_time.h"
 
 // Helper macro to simplify some of the control flow.
 #define RETURN_IF_ERROR_AND_LOG(expr)                            \
@@ -67,8 +66,8 @@
 void TrustRegionMinimizer::Minimize(const Minimizer::Options& options,
                                     double* parameters,
                                     Solver::Summary* solver_summary) {
-  start_time_in_secs_ = WallTimeInSeconds();
-  iteration_start_time_in_secs_ = start_time_in_secs_;
+  start_time_ = absl::Now();
+  iteration_start_time_ = start_time_;
   Init(options, parameters, solver_summary);
   RETURN_IF_ERROR_AND_LOG(IterationZero());
 
@@ -83,7 +82,7 @@
 
   bool atleast_one_successful_step = false;
   while (FinalizeIterationAndCheckIfMinimizerCanContinue()) {
-    iteration_start_time_in_secs_ = WallTimeInSeconds();
+    iteration_start_time_ = absl::Now();
 
     const double previous_gradient_norm = iteration_summary_.gradient_norm;
     const double previous_gradient_max_norm =
@@ -327,10 +326,11 @@
   }
 
   iteration_summary_.trust_region_radius = strategy_->Radius();
+  const absl::Time now = absl::Now();
   iteration_summary_.iteration_time_in_seconds =
-      WallTimeInSeconds() - iteration_start_time_in_secs_;
+      absl::ToDoubleSeconds(now - iteration_start_time_);
   iteration_summary_.cumulative_time_in_seconds =
-      WallTimeInSeconds() - start_time_in_secs_ +
+      absl::ToDoubleSeconds(now - start_time_) +
       solver_summary_->preprocessor_time_in_seconds;
 
   solver_summary_->iterations.push_back(iteration_summary_);
@@ -377,7 +377,7 @@
 // negative. In which case again, we set
 // iteration_summary_.step_is_valid to false.
 bool TrustRegionMinimizer::ComputeTrustRegionStep() {
-  const double strategy_start_time = WallTimeInSeconds();
+  const absl::Time strategy_start_time = absl::Now();
   iteration_summary_.step_is_valid = false;
   TrustRegionStrategy::PerSolveOptions per_solve_options;
   per_solve_options.eta = options_.eta;
@@ -409,7 +409,7 @@
   }
 
   iteration_summary_.step_solver_time_in_seconds =
-      WallTimeInSeconds() - strategy_start_time;
+      absl::ToDoubleSeconds(absl::Now() - strategy_start_time);
   iteration_summary_.linear_solver_iterations = strategy_summary.num_iterations;
 
   if (strategy_summary.termination_type ==
@@ -511,7 +511,7 @@
     return;
   }
 
-  double inner_iteration_start_time = WallTimeInSeconds();
+  const absl::Time inner_iteration_start_time = absl::Now();
   ++solver_summary_->num_inner_iteration_steps;
   inner_iteration_x_ = candidate_x_;
   Solver::Summary inner_iteration_summary;
@@ -575,7 +575,7 @@
   candidate_cost_ = inner_iteration_cost;
 
   solver_summary_->inner_iteration_time_in_seconds +=
-      WallTimeInSeconds() - inner_iteration_start_time;
+      absl::ToDoubleSeconds(absl::Now() - inner_iteration_start_time);
 }
 
 // Perform a projected line search to improve the objective function
@@ -619,13 +619,13 @@
 
   solver_summary_->num_line_search_steps += line_search_summary.num_iterations;
   solver_summary_->line_search_cost_evaluation_time_in_seconds +=
-      line_search_summary.cost_evaluation_time_in_seconds;
+      absl::ToDoubleSeconds(line_search_summary.cost_evaluation_time);
   solver_summary_->line_search_gradient_evaluation_time_in_seconds +=
-      line_search_summary.gradient_evaluation_time_in_seconds;
+      absl::ToDoubleSeconds(line_search_summary.gradient_evaluation_time);
   solver_summary_->line_search_polynomial_minimization_time_in_seconds +=
-      line_search_summary.polynomial_minimization_time_in_seconds;
+      absl::ToDoubleSeconds(line_search_summary.polynomial_minimization_time);
   solver_summary_->line_search_total_time_in_seconds +=
-      line_search_summary.total_time_in_seconds;
+      absl::ToDoubleSeconds(line_search_summary.total_time);
 
   if (line_search_summary.success) {
     *delta *= line_search_summary.optimal_point.x;
@@ -637,7 +637,7 @@
 // Solver::Summary::message.
 bool TrustRegionMinimizer::MaxSolverTimeReached() {
   const double total_solver_time =
-      WallTimeInSeconds() - start_time_in_secs_ +
+      absl::ToDoubleSeconds(absl::Now() - start_time_) +
       solver_summary_->preprocessor_time_in_seconds;
   if (total_solver_time < options_.max_solver_time_in_seconds) {
     return false;
diff --git a/internal/ceres/trust_region_minimizer.h b/internal/ceres/trust_region_minimizer.h
index c9cdac7..91f9deb 100644
--- a/internal/ceres/trust_region_minimizer.h
+++ b/internal/ceres/trust_region_minimizer.h
@@ -33,6 +33,7 @@
 
 #include <memory>
 
+#include "absl/time/time.h"
 #include "ceres/internal/disable_warnings.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/internal/export.h"
@@ -149,9 +150,9 @@
   double candidate_cost_;
 
   // Time at which the minimizer was started.
-  double start_time_in_secs_;
+  absl::Time start_time_;
   // Time at which the current iteration was started.
-  double iteration_start_time_in_secs_;
+  absl::Time iteration_start_time_;
   // Number of consecutive steps where the minimizer loop computed a
   // numerically invalid step.
   int num_consecutive_invalid_steps_;
diff --git a/internal/ceres/trust_region_preprocessor.cc b/internal/ceres/trust_region_preprocessor.cc
index 4d20f52..0ec94f4 100644
--- a/internal/ceres/trust_region_preprocessor.cc
+++ b/internal/ceres/trust_region_preprocessor.cc
@@ -50,7 +50,6 @@
 #include "ceres/reorder_program.h"
 #include "ceres/suitesparse.h"
 #include "ceres/trust_region_strategy.h"
-#include "ceres/wall_time.h"
 
 namespace ceres::internal {