diff --git a/src/Avalonia.Base/Reactive/LightweightObservableBase.cs b/src/Avalonia.Base/Reactive/LightweightObservableBase.cs index 41009e4cd3..f5052e5858 100644 --- a/src/Avalonia.Base/Reactive/LightweightObservableBase.cs +++ b/src/Avalonia.Base/Reactive/LightweightObservableBase.cs @@ -116,20 +116,33 @@ namespace Avalonia.Reactive { if (Volatile.Read(ref _observers) != null) { - IObserver[] observers; - + IObserver[] observers = null; + IObserver singleObserver = null; lock (this) { if (_observers == null) { return; } - observers = _observers.ToArray(); + if (_observers.Count == 1) + { + singleObserver = _observers[0]; + } + else + { + observers = _observers.ToArray(); + } } - - foreach (var observer in observers) + if (singleObserver != null) { - observer.OnNext(value); + singleObserver.OnNext(value); + } + else + { + foreach (var observer in observers) + { + observer.OnNext(value); + } } } } diff --git a/tests/Avalonia.Benchmarks/Data/BindingsBenchmark.cs b/tests/Avalonia.Benchmarks/Data/BindingsBenchmark.cs index d1ca77c980..a320f07063 100644 --- a/tests/Avalonia.Benchmarks/Data/BindingsBenchmark.cs +++ b/tests/Avalonia.Benchmarks/Data/BindingsBenchmark.cs @@ -19,6 +19,22 @@ namespace Avalonia.Benchmarks.Data instance.Bind(TestClass.IntValueProperty, binding); } + [Benchmark] + public void UpdateTwoWayBinding_Via_Binding() + { + var instance = new TestClass(); + + var binding = new Binding(nameof(TestClass.BoundValue), BindingMode.TwoWay) + { + Source = instance + }; + + instance.Bind(TestClass.IntValueProperty, binding); + for (int i = 0; i < 60; i++) + { + instance.IntValue = i; + } + } private class TestClass : AvaloniaObject { public static readonly StyledProperty IntValueProperty =