From f3b61f0b8446b1ff812368747d782fb215d3eef1 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 14 Oct 2025 17:57:40 +0200 Subject: [PATCH] property_tracker: don't register dependencies for tracker that don't have dependencies themselves This saves 3% of dependencies in my benchmark --- internal/core/properties.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/internal/core/properties.rs b/internal/core/properties.rs index 9a44380f0c2..b81cd012285 100644 --- a/internal/core/properties.rs +++ b/internal/core/properties.rs @@ -67,6 +67,11 @@ mod single_linked_list_pin { } I(&self.0) } + + /// Returns true if the list is empty + pub fn is_empty(&self) -> bool { + self.0.is_none() + } } #[test] @@ -1436,6 +1441,12 @@ impl PropertyTracker { /// Register this property tracker as a dependency to the current binding/property tracker being evaluated pub fn register_as_dependency_to_current_binding(self: Pin<&Self>) { + let dep_nodes = self.holder.dep_nodes.take(); + if dep_nodes.is_empty() { + // No need to register dependency if we have no dependency ourselves + return; + } + self.holder.dep_nodes.set(dep_nodes); if CURRENT_BINDING.is_set() { CURRENT_BINDING.with(|cur_binding| { if let Some(cur_binding) = cur_binding { @@ -1463,8 +1474,9 @@ impl PropertyTracker { /// If this is called during the evaluation of another property binding or property tracker, then /// any changes to accessed properties will also mark the other binding/tracker dirty. pub fn evaluate(self: Pin<&Self>, f: impl FnOnce() -> R) -> R { + let r = self.evaluate_as_dependency_root(f); self.register_as_dependency_to_current_binding(); - self.evaluate_as_dependency_root(f) + r } /// Evaluate the function, and record dependencies of properties accessed within this function. @@ -1488,8 +1500,9 @@ impl PropertyTracker { /// Call [`Self::evaluate`] if and only if it is dirty. /// But register a dependency in any case. pub fn evaluate_if_dirty(self: Pin<&Self>, f: impl FnOnce() -> R) -> Option { + let r = self.is_dirty().then(|| self.evaluate_as_dependency_root(f)); self.register_as_dependency_to_current_binding(); - self.is_dirty().then(|| self.evaluate_as_dependency_root(f)) + r } /// Mark this PropertyTracker as dirty