From 35ee4f79762f933ca12ad27c9a3bb7201cc24dcd Mon Sep 17 00:00:00 2001 From: ahopper Date: Wed, 20 Nov 2019 11:04:20 +0000 Subject: [PATCH 1/3] Reduce calls to ToArray in PublishNext --- .../Reactive/LightweightObservableBase.cs | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/Avalonia.Base/Reactive/LightweightObservableBase.cs b/src/Avalonia.Base/Reactive/LightweightObservableBase.cs index 41009e4cd3..b6c7cecfdc 100644 --- a/src/Avalonia.Base/Reactive/LightweightObservableBase.cs +++ b/src/Avalonia.Base/Reactive/LightweightObservableBase.cs @@ -111,25 +111,38 @@ namespace Avalonia.Reactive protected abstract void Initialize(); protected abstract void Deinitialize(); - + protected void PublishNext(T value) { 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); + } } } } From f7c644eb7567a865b95c3ba9dc95f9398d5969a7 Mon Sep 17 00:00:00 2001 From: ahopper Date: Wed, 20 Nov 2019 11:14:48 +0000 Subject: [PATCH 2/3] whitespace --- src/Avalonia.Base/Reactive/LightweightObservableBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Avalonia.Base/Reactive/LightweightObservableBase.cs b/src/Avalonia.Base/Reactive/LightweightObservableBase.cs index b6c7cecfdc..f5052e5858 100644 --- a/src/Avalonia.Base/Reactive/LightweightObservableBase.cs +++ b/src/Avalonia.Base/Reactive/LightweightObservableBase.cs @@ -111,7 +111,7 @@ namespace Avalonia.Reactive protected abstract void Initialize(); protected abstract void Deinitialize(); - + protected void PublishNext(T value) { if (Volatile.Read(ref _observers) != null) From 8879d4c92d97dac93b9e659950f47f87da005c9e Mon Sep 17 00:00:00 2001 From: ahopper Date: Wed, 20 Nov 2019 16:12:09 +0000 Subject: [PATCH 3/3] added benchmark --- .../Data/BindingsBenchmark.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) 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 =