فهرست منبع

Optimize ToHashSet.

Bart De Smet 7 سال پیش
والد
کامیت
91ba295ed9
1فایلهای تغییر یافته به همراه24 افزوده شده و 11 حذف شده
  1. 24 11
      Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToHashSet.cs

+ 24 - 11
Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToHashSet.cs

@@ -15,7 +15,7 @@ namespace System.Linq
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
 
-            return ToHashSet(source, EqualityComparer<TSource>.Default, CancellationToken.None);
+            return ToHashSetCore(source, EqualityComparer<TSource>.Default, CancellationToken.None);
         }
 
         public static Task<HashSet<TSource>> ToHashSet<TSource>(this IAsyncEnumerable<TSource> source, CancellationToken cancellationToken)
@@ -23,7 +23,7 @@ namespace System.Linq
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
 
-            return ToHashSet(source, EqualityComparer<TSource>.Default, cancellationToken);
+            return ToHashSetCore(source, EqualityComparer<TSource>.Default, cancellationToken);
         }
 
         public static Task<HashSet<TSource>> ToHashSet<TSource>(this IAsyncEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
@@ -33,7 +33,7 @@ namespace System.Linq
             if (comparer == null)
                 throw new ArgumentNullException(nameof(comparer));
 
-            return ToHashSet(source, comparer, CancellationToken.None);
+            return ToHashSetCore(source, comparer, CancellationToken.None);
         }
 
         public static Task<HashSet<TSource>> ToHashSet<TSource>(this IAsyncEnumerable<TSource> source, IEqualityComparer<TSource> comparer, CancellationToken cancellationToken)
@@ -43,15 +43,28 @@ namespace System.Linq
             if (comparer == null)
                 throw new ArgumentNullException(nameof(comparer));
 
-            return source.Aggregate(
-                new HashSet<TSource>(comparer),
-                (set, x) =>
+            return ToHashSetCore(source, comparer, cancellationToken);
+        }
+
+        private static async Task<HashSet<TSource>> ToHashSetCore<TSource>(IAsyncEnumerable<TSource> source, IEqualityComparer<TSource> comparer, CancellationToken cancellationToken)
+        {
+            var e = source.GetAsyncEnumerator(cancellationToken);
+
+            try
+            {
+                var set = new HashSet<TSource>(comparer);
+
+                while (await e.MoveNextAsync().ConfigureAwait(false))
                 {
-                    set.Add(x);
-                    return set;
-                },
-                cancellationToken
-            );
+                    set.Add(e.Current);
+                }
+
+                return set;
+            }
+            finally
+            {
+                await e.DisposeAsync().ConfigureAwait(false);
+            }
         }
     }
 }