Browse Source

Improving memory usage of ImmutableList.

Bart De Smet 10 years ago
parent
commit
def30a70b7

+ 9 - 3
Rx.NET/Source/System.Reactive.Core/Reactive/Internal/ImmutableList.cs

@@ -4,9 +4,11 @@ namespace System.Reactive
 {
     internal class ImmutableList<T>
     {
+        public static readonly ImmutableList<T> Empty = new ImmutableList<T>();
+
         private readonly T[] _data;
 
-        public ImmutableList()
+        private ImmutableList()
         {
             _data = new T[0];
         }
@@ -40,10 +42,14 @@ namespace System.Reactive
             if (i < 0)
                 return this;
 
-            var newData = new T[_data.Length - 1];
+            var length = _data.Length;
+            if (length == 1)
+                return Empty;
+
+            var newData = new T[length - 1];
 
             Array.Copy(_data, 0, newData, 0, i);
-            Array.Copy(_data, i + 1, newData, i, _data.Length - i - 1);
+            Array.Copy(_data, i + 1, newData, i, length - i - 1);
 
             return new ImmutableList<T>(newData);
         }

+ 3 - 3
Rx.NET/Source/System.Reactive.Linq/Reactive/Subjects/AsyncSubject.cs

@@ -31,7 +31,7 @@ namespace System.Reactive.Subjects
         /// </summary>
         public AsyncSubject()
         {
-            _observers = new ImmutableList<IObserver<T>>();
+            _observers = ImmutableList<IObserver<T>>.Empty;
         }
 
         /// <summary>
@@ -62,7 +62,7 @@ namespace System.Reactive.Subjects
                 if (!_isStopped)
                 {
                     os = _observers.Data;
-                    _observers = new ImmutableList<IObserver<T>>();
+                    _observers = ImmutableList<IObserver<T>>.Empty;
                     _isStopped = true;
                     v = _value;
                     hv = _hasValue;
@@ -103,7 +103,7 @@ namespace System.Reactive.Subjects
                 if (!_isStopped)
                 {
                     os = _observers.Data;
-                    _observers = new ImmutableList<IObserver<T>>();
+                    _observers = ImmutableList<IObserver<T>>.Empty;
                     _isStopped = true;
                     _exception = error;
                 }

+ 3 - 3
Rx.NET/Source/System.Reactive.Linq/Reactive/Subjects/BehaviorSubject.cs

@@ -26,7 +26,7 @@ namespace System.Reactive.Subjects
         public BehaviorSubject(T value)
         {
             _value = value;
-            _observers = new ImmutableList<IObserver<T>>();
+            _observers = ImmutableList<IObserver<T>>.Empty;
         }
 
         /// <summary>
@@ -86,7 +86,7 @@ namespace System.Reactive.Subjects
                 if (!_isStopped)
                 {
                     os = _observers.Data;
-                    _observers = new ImmutableList<IObserver<T>>();
+                    _observers = ImmutableList<IObserver<T>>.Empty;
                     _isStopped = true;
                 }
             }
@@ -116,7 +116,7 @@ namespace System.Reactive.Subjects
                 if (!_isStopped)
                 {
                     os = _observers.Data;
-                    _observers = new ImmutableList<IObserver<T>>();
+                    _observers = ImmutableList<IObserver<T>>.Empty;
                     _isStopped = true;
                     _exception = error;
                 }

+ 6 - 6
Rx.NET/Source/System.Reactive.Linq/Reactive/Subjects/ReplaySubject.cs

@@ -233,7 +233,7 @@ namespace System.Reactive.Subjects
                 _isStopped = false;
                 _error = null;
 
-                _observers = new ImmutableList<ScheduledObserver<T>>();
+                _observers = ImmutableList<ScheduledObserver<T>>.Empty;
             }
 
             public ReplayByTime(int bufferSize, TimeSpan window)
@@ -323,7 +323,7 @@ namespace System.Reactive.Subjects
                         foreach (var observer in o)
                             observer.OnError(error);
 
-                        _observers = new ImmutableList<ScheduledObserver<T>>();
+                        _observers = ImmutableList<ScheduledObserver<T>>.Empty;
                     }
                 }
 
@@ -349,7 +349,7 @@ namespace System.Reactive.Subjects
                         foreach (var observer in o)
                             observer.OnCompleted();
 
-                        _observers = new ImmutableList<ScheduledObserver<T>>();
+                        _observers = ImmutableList<ScheduledObserver<T>>.Empty;
                     }
                 }
 
@@ -550,7 +550,7 @@ namespace System.Reactive.Subjects
 
             protected ReplayBufferBase()
             {
-                _observers = new ImmutableList<IObserver<T>>();
+                _observers = ImmutableList<IObserver<T>>.Empty;
             }
 
             protected abstract void Trim();
@@ -603,7 +603,7 @@ namespace System.Reactive.Subjects
                         foreach (var observer in o)
                             observer.OnError(error);
 
-                        _observers = new ImmutableList<IObserver<T>>();
+                        _observers = ImmutableList<IObserver<T>>.Empty;
                     }
                 }
             }
@@ -623,7 +623,7 @@ namespace System.Reactive.Subjects
                         foreach (var observer in o)
                             observer.OnCompleted();
 
-                        _observers = new ImmutableList<IObserver<T>>();
+                        _observers = ImmutableList<IObserver<T>>.Empty;
                     }
                 }
             }

+ 2 - 2
Rx.NET/Source/Tests.System.Reactive/Tests/ImmutableListTest.cs

@@ -11,7 +11,7 @@ namespace ReactiveTests.Tests
         [TestMethod]
         public void ImmutableList_Basics()
         {
-            var list = new ImmutableList<int>();
+            var list = ImmutableList<int>.Empty;
 
             Assert.IsTrue(list.Data.SequenceEqual(new int[] { }));
 
@@ -49,7 +49,7 @@ namespace ReactiveTests.Tests
         [TestMethod]
         public void ImmutableList_Nulls()
         {
-            var list = new ImmutableList<string>();
+            var list = ImmutableList<string>.Empty;
 
             Assert.IsTrue(list.Data.SequenceEqual(new string[] { }));