historical_latencies_container.cc 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. // Copyright 2022 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/network_time/historical_latencies_container.h"
  5. #include <cmath>
  6. #include "base/metrics/field_trial_params.h"
  7. #include "base/numerics/checked_math.h"
  8. #include "base/numerics/safe_conversions.h"
  9. #include "base/time/time.h"
  10. #include "components/network_time/network_time_tracker.h"
  11. #include "third_party/abseil-cpp/absl/types/optional.h"
  12. namespace network_time {
  13. // Number of previous latencies to use for computing the standard deviation.
  14. // Should be greater or equal 0 and less or equal kMaxNumHistoricalLatencies. If
  15. // 0, the standard deviation will not be reported.
  16. constexpr base::FeatureParam<int> kNumHistoricalLatencies{
  17. &kNetworkTimeServiceQuerying, "NumHistoricalLatencies", 3};
  18. void HistoricalLatenciesContainer::Record(base::TimeDelta latency) {
  19. latencies_.SaveToBuffer(latency);
  20. }
  21. absl::optional<base::TimeDelta> HistoricalLatenciesContainer::StdDeviation()
  22. const {
  23. int num_historical_latencies = kNumHistoricalLatencies.Get();
  24. if (num_historical_latencies <= 0 ||
  25. num_historical_latencies > kMaxNumHistoricalLatencies) {
  26. return absl::nullopt;
  27. }
  28. base::CheckedNumeric<int64_t> mean;
  29. {
  30. auto it = latencies_.End();
  31. for (int i = 0; i < num_historical_latencies; ++i, --it) {
  32. if (!it) // Less than `num_historical_latencies` recorded so far.
  33. return absl::nullopt;
  34. mean += it->InMicroseconds();
  35. }
  36. mean = mean / num_historical_latencies;
  37. }
  38. base::CheckedNumeric<int64_t> variance;
  39. {
  40. auto it = latencies_.End();
  41. for (int i = 0; i < num_historical_latencies; ++i, --it) {
  42. base::CheckedNumeric<int64_t> diff_from_mean =
  43. mean - it->InMicroseconds();
  44. variance += diff_from_mean * diff_from_mean;
  45. }
  46. }
  47. if (!variance.IsValid())
  48. return absl::nullopt;
  49. base::TimeDelta std_deviation = base::Microseconds(
  50. std::lround(std::sqrt(base::strict_cast<double>(variance.ValueOrDie()))));
  51. if (std_deviation.is_inf())
  52. return absl::nullopt;
  53. return std_deviation;
  54. }
  55. } // namespace network_time