react-native-macos/ReactCommon/utils/Telemetry.h

66 строки
1.7 KiB
C
Исходник Обычный вид История

Fabric: Improving precision and type-safety of Telemetry Summary: Collecting Telemetry is a crucial part of building a performant UI framework; we do that but we need to improve it to make the data more reliable, actionable and trustful. Now we collect time points as the number of milliseconds from the start of the CLOCK_MONOTONIC epoch. That's fine but it also has problems: Sometimes a millisecond is an eternity. We have only 16 (or fewer) of them on each frame. What if some operation takes 1ms (according to telemetry) but we have to run it a dozen times? Does it mean that it's 12 ms in total? So, we lack precision. This is not type-safe. Do you know how many milliseconds in a microsecond? I don't. We multiply that on magical constants hoping that we copied that from some other place right. The current implementation is not cross-platform. We have ifdefs for iOS and Android and Unix and Windows (which is now implemented). So, this diff replaces that with using `std::chrono` which is part of the standard library that designed to fix all those concerns. We also define our type-aliases on top of that to express our concrete constrains: We use `std::chrono::steady_clock` as the base clock which is according to the standard using `clock_gettime(CLOCK_MONOTONIC, ... )` if available. So, it's fast and compatible (the same under the hood) with Android infra. We use nanoseconds when we store time durations (TelemetryDuration type). Changelog: [Internal] Fabric-specific internal change. Reviewed By: JoshuaGross, mdvacca Differential Revision: D19184569 fbshipit-source-id: 7a44688f4bb3bfc6e3009874f0075c531c8569a1
2020-01-28 00:23:09 +03:00
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <chrono>
namespace facebook {
namespace react {
/*
* Represents a monotonic clock suitable for measuring intervals.
*/
using TelemetryClock = std::chrono::steady_clock;
/*
* Represents a point in time satisfied the requirements of TelemetryClock.
*/
using TelemetryTimePoint = TelemetryClock::time_point;
/*
* Represents a time interval satisfied the requirements of TelemetryClock.
*/
using TelemetryDuration = std::chrono::nanoseconds;
/*
* Represents a time point which never happens.
*/
static TelemetryTimePoint const kTelemetryUndefinedTimePoint =
TelemetryTimePoint::max();
/*
* Returns a time point representing the current point in time.
*/
static inline TelemetryTimePoint telemetryTimePointNow() {
return TelemetryClock::now();
}
/*
* Returns a number of milliseconds that passed from some epoch starting time
* point to a given time point. The epoch starting time point is not specified
* but stays the same for an application run.
*/
static inline int64_t telemetryTimePointToMilliseconds(
TelemetryTimePoint timePoint) {
return std::chrono::duration_cast<std::chrono::milliseconds>(
timePoint - TelemetryTimePoint{})
.count();
}
/*
* Returns a number of milliseconds that represents the given duration object.
*/
static inline int64_t telemetryDurationToMilliseconds(
TelemetryDuration duration) {
return std::chrono::duration_cast<std::chrono::milliseconds>(duration)
.count();
}
} // namespace react
} // namespace facebook