From a6b69b309abf36b8a397c37b88a4add753e3988b Mon Sep 17 00:00:00 2001 From: Marc Rousavy <me@mrousavy.com> Date: Sun, 23 Jun 2024 12:27:04 +0200 Subject: [PATCH] perf: Speed up Dispatcher get calls --- .../cpp/threading/Dispatcher.cpp | 16 ++++++++++++++++ .../cpp/threading/Dispatcher.hpp | 3 +++ 2 files changed, 19 insertions(+) diff --git a/packages/react-native-nitro-modules/cpp/threading/Dispatcher.cpp b/packages/react-native-nitro-modules/cpp/threading/Dispatcher.cpp index d3929f8c8..11e3ae4bc 100644 --- a/packages/react-native-nitro-modules/cpp/threading/Dispatcher.cpp +++ b/packages/react-native-nitro-modules/cpp/threading/Dispatcher.cpp @@ -7,15 +7,31 @@ using namespace facebook; static constexpr auto GLOBAL_DISPATCHER_HOLDER_NAME = "__nitroDispatcher"; +std::unordered_map<jsi::Runtime*, std::weak_ptr<Dispatcher>> Dispatcher::_globalCache; + void Dispatcher::installRuntimeGlobalDispatcher(jsi::Runtime& runtime, std::shared_ptr<Dispatcher> dispatcher) { Logger::log(TAG, "Installing global Dispatcher Holder..."); + + // Store a weak reference in global cache + _globalCache[&runtime] = std::weak_ptr(dispatcher); + // Inject the dispatcher into Runtime global (runtime will hold a strong reference) jsi::Object dispatcherHolder(runtime); dispatcherHolder.setNativeState(runtime, dispatcher); runtime.global().setProperty(runtime, GLOBAL_DISPATCHER_HOLDER_NAME, dispatcherHolder); } std::shared_ptr<Dispatcher> Dispatcher::getRuntimeGlobalDispatcher(jsi::Runtime& runtime) { + if (_globalCache.contains(&runtime)) [[likely]] { + // the runtime is known - we have something in cache + std::weak_ptr<Dispatcher> weakDispatcher = _globalCache[&runtime]; + std::shared_ptr<Dispatcher> strongDispatcher = weakDispatcher.lock(); + if (strongDispatcher) { + // the weak reference we cached is still valid - return it! + return strongDispatcher; + } + } + jsi::Value dispatcherHolderValue = getRuntimeGlobalDispatcherHolder(runtime); jsi::Object dispatcherHolder = dispatcherHolderValue.getObject(runtime); return dispatcherHolder.getNativeState<Dispatcher>(runtime); diff --git a/packages/react-native-nitro-modules/cpp/threading/Dispatcher.hpp b/packages/react-native-nitro-modules/cpp/threading/Dispatcher.hpp index 00db74759..59089b710 100644 --- a/packages/react-native-nitro-modules/cpp/threading/Dispatcher.hpp +++ b/packages/react-native-nitro-modules/cpp/threading/Dispatcher.hpp @@ -70,6 +70,9 @@ class Dispatcher : public jsi::NativeState { // 3. Return an open future that gets resolved later by the dispatcher Thread return future; } + +private: + static std::unordered_map<jsi::Runtime*, std::weak_ptr<Dispatcher>> _globalCache; private: static constexpr auto TAG = "Dispatcher";