Unify native performanceNow implementation across platforms

Summary:
[Changelog][Internal]

Both iOS and Android platforms are at this point using the same native implementation of `performanceNow`, based on `std::chrono` (it used to be different some time ago).

This diff unifies the implementations, so it comes from one place in C++ code for all platforms.

The context is that I am developing event timing instrumentation and need a consistent way to get current timestamp from either JS or native (C++) side. The latter is now possible via calling `JSExecutor::performanceNow()`, which is guaranteed to be the same as called from JS.

Reviewed By: christophpurrer

Differential Revision: D42267898

fbshipit-source-id: dcb592f37d6567340ea59faddbf3b6d2b8507d50
This commit is contained in:
Ruslan Shestopalyuk 2022-12-28 11:03:14 -08:00 коммит произвёл Facebook GitHub Bot
Родитель 673d7e81a2
Коммит ad953f6f4b
9 изменённых файлов: 25 добавлений и 72 удалений

Просмотреть файл

@ -20,16 +20,7 @@ JSIExecutor::RuntimeInstaller RCTJSIExecutorRuntimeInstaller(JSIExecutor::Runtim
_RCTLogJavaScriptInternal(static_cast<RCTLogLevel>(logLevel), [NSString stringWithUTF8String:message.c_str()]);
};
bindNativeLogger(runtime, iosLoggingBinder);
PerformanceNow iosPerformanceNowBinder = []() {
auto time = std::chrono::steady_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(time.time_since_epoch()).count();
constexpr double NANOSECONDS_IN_MILLISECOND = 1000000.0;
return duration / NANOSECONDS_IN_MILLISECOND;
};
bindNativePerformanceNow(runtime, iosPerformanceNowBinder);
bindNativePerformanceNow(runtime);
// Wrap over the original runtimeInstaller
if (runtimeInstaller) {

Просмотреть файл

@ -16,7 +16,6 @@
#include <react/jni/JReactMarker.h>
#include <react/jni/JSLogging.h>
#include <react/jni/JavaScriptExecutorHolder.h>
#include <react/jni/NativeTime.h>
#include <memory>
@ -56,10 +55,7 @@ static void installBindings(jsi::Runtime &runtime) {
static_cast<void (*)(const std::string &, unsigned int)>(
&reactAndroidLoggingHook);
react::bindNativeLogger(runtime, androidLogger);
react::PerformanceNow androidNativePerformanceNow =
static_cast<double (*)()>(&reactAndroidNativePerformanceNowHook);
react::bindNativePerformanceNow(runtime, androidNativePerformanceNow);
react::bindNativePerformanceNow(runtime);
}
class HermesExecutorHolder

Просмотреть файл

@ -1,26 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "NativeTime.h"
#include <chrono>
namespace facebook {
namespace react {
double reactAndroidNativePerformanceNowHook() {
auto time = std::chrono::steady_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(
time.time_since_epoch())
.count();
constexpr double NANOSECONDS_IN_MILLISECOND = 1000000.0;
return duration / NANOSECONDS_IN_MILLISECOND;
}
} // namespace react
} // namespace facebook

Просмотреть файл

@ -1,16 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and 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
namespace facebook {
namespace react {
double reactAndroidNativePerformanceNowHook();
} // namespace react
} // namespace facebook

Просмотреть файл

@ -11,7 +11,6 @@
#include <react/jni/JReactMarker.h>
#include <react/jni/JSLogging.h>
#include <react/jni/JavaScriptExecutorHolder.h>
#include <react/jni/NativeTime.h>
#include <react/jni/ReadableNativeMap.h>
#include <memory>
@ -31,10 +30,7 @@ class JSCExecutorFactory : public JSExecutorFactory {
static_cast<void (*)(const std::string &, unsigned int)>(
&reactAndroidLoggingHook);
react::bindNativeLogger(runtime, androidLogger);
react::PerformanceNow androidNativePerformanceNow =
static_cast<double (*)()>(&reactAndroidNativePerformanceNowHook);
react::bindNativePerformanceNow(runtime, androidNativePerformanceNow);
react::bindNativePerformanceNow(runtime);
};
return std::make_unique<JSIExecutor>(
jsc::makeJSCRuntime(),

Просмотреть файл

@ -11,6 +11,8 @@
#include <folly/Conv.h>
#include <chrono>
namespace facebook {
namespace react {
@ -23,5 +25,15 @@ std::string JSExecutor::getSyntheticBundlePath(
return folly::to<std::string>("seg-", bundleId, ".js");
}
double JSExecutor::performanceNow() {
auto time = std::chrono::steady_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(
time.time_since_epoch())
.count();
constexpr double NANOSECONDS_IN_MILLISECOND = 1000000.0;
return duration / NANOSECONDS_IN_MILLISECOND;
}
} // namespace react
} // namespace facebook

Просмотреть файл

@ -138,6 +138,8 @@ class RN_EXPORT JSExecutor {
static std::string getSyntheticBundlePath(
uint32_t bundleId,
const std::string &bundlePath);
static double performanceNow();
};
} // namespace react

Просмотреть файл

@ -565,7 +565,7 @@ void bindNativeLogger(Runtime &runtime, Logger logger) {
}));
}
void bindNativePerformanceNow(Runtime &runtime, PerformanceNow performanceNow) {
void bindNativePerformanceNow(Runtime &runtime) {
runtime.global().setProperty(
runtime,
"nativePerformanceNow",
@ -573,11 +573,10 @@ void bindNativePerformanceNow(Runtime &runtime, PerformanceNow performanceNow) {
runtime,
PropNameID::forAscii(runtime, "nativePerformanceNow"),
0,
[performanceNow = std::move(performanceNow)](
jsi::Runtime &runtime,
[](jsi::Runtime &runtime,
const jsi::Value &,
const jsi::Value *args,
size_t count) { return Value(performanceNow()); }));
size_t count) { return Value(JSExecutor::performanceNow()); }));
}
} // namespace react

Просмотреть файл

@ -137,9 +137,8 @@ using Logger =
std::function<void(const std::string &message, unsigned int logLevel)>;
void bindNativeLogger(jsi::Runtime &runtime, Logger logger);
using PerformanceNow = std::function<double()>;
void bindNativePerformanceNow(
jsi::Runtime &runtime,
PerformanceNow performanceNow);
void bindNativePerformanceNow(jsi::Runtime &runtime);
double performanceNow();
} // namespace react
} // namespace facebook