Remove more unnecessary LINQ usage (#33892)
authorStephen Toub <stoub@microsoft.com>
Sat, 21 Mar 2020 12:15:46 +0000 (08:15 -0400)
committerGitHub <noreply@github.com>
Sat, 21 Mar 2020 12:15:46 +0000 (08:15 -0400)
12 files changed:
src/libraries/System.ComponentModel.Composition/src/Microsoft/Internal/Collections/CollectionServices.cs
src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/CompositionResult.cs
src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/CompositionResultOfT.cs
src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/AggregateExportProvider.cs
src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/FilteredCatalog.cs
src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/ImportEngine.PartManager.cs
src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.NonUap.cs
src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Unix.cs
src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Win32.cs
src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/BlockExpression.cs
src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Statements.cs
src/libraries/System.Net.WebHeaderCollection/src/System/Net/HeaderInfoTable.cs

index 6a1af13..a4d6324 100644 (file)
@@ -69,12 +69,12 @@ namespace Microsoft.Internal.Collections
 
         public static IEnumerable<T>? ConcatAllowingNull<T>(this IEnumerable<T>? source, IEnumerable<T>? second)
         {
-            if (second == null || !second.FastAny())
+            if (second == null || !second.Any())
             {
                 return source;
             }
 
-            if (source == null || !source.FastAny())
+            if (source == null || !source.Any())
             {
                 return second;
             }
@@ -203,23 +203,6 @@ namespace Microsoft.Internal.Collections
             }
         }
 
-        public static bool FastAny<T>(this IEnumerable<T> source)
-        {
-            // Enumerable.Any<T> underneath doesn't cast to ICollection,
-            // like it does with many of the other LINQ methods.
-            // Below is significantly (4x) when mainly working with ICollection
-            // sources and a little slower if working with mainly IEnumerable<T>
-            // sources.
-
-            // Cast to ICollection instead of ICollection<T> for performance reasons.
-            if (source is ICollection collection)
-            {
-                return collection.Count > 0;
-            }
-
-            return source.Any();
-        }
-
         public static Stack<T> Copy<T>(this Stack<T> stack)
         {
             if (stack == null)
index 4b4859f..663372b 100644 (file)
@@ -26,7 +26,7 @@ namespace System.ComponentModel.Composition
 
         public bool Succeeded
         {
-            get { return _errors == null || !_errors.FastAny(); }
+            get { return _errors == null || !_errors.Any(); }
         }
 
         public IEnumerable<CompositionError> Errors
index 12c1339..98a491f 100644 (file)
@@ -37,7 +37,7 @@ namespace System.ComponentModel.Composition
 
         public bool Succeeded
         {
-            get { return _errors == null || !_errors.FastAny(); }
+            get { return _errors == null || !_errors.Any(); }
         }
 
         public IEnumerable<CompositionError> Errors
index 84a4e48..9250e96 100644 (file)
@@ -179,7 +179,7 @@ namespace System.ComponentModel.Composition.Hosting
                 {
                     bool cardinalityCheckResult = provider.TryGetExports(definition, atomicComposition, out IEnumerable<Export>? exports);
                     Debug.Assert(exports != null);
-                    bool anyExports = exports.FastAny();
+                    bool anyExports = exports.Any();
                     if (cardinalityCheckResult && anyExports)
                     {
                         // NOTE : if the provider returned nothing, we need to proceed, even if it indicated that the
index 6b39064..2c7ba12 100644 (file)
@@ -230,7 +230,7 @@ namespace System.ComponentModel.Composition.Hosting
                 e.AtomicComposition);
 
             // Only fire if we need to
-            if (result.AddedDefinitions.FastAny() || result.RemovedDefinitions.FastAny())
+            if (result.AddedDefinitions.Any() || result.RemovedDefinitions.Any())
             {
                 return result;
             }
index 9adc214..08e34ec 100644 (file)
@@ -174,7 +174,7 @@ namespace System.ComponentModel.Composition.Hosting
                     if (disposableExports == null)
                     {
                         _importedDisposableExports.Remove(import);
-                        if (!_importedDisposableExports.FastAny())
+                        if (!_importedDisposableExports.Any())
                         {
                             _importedDisposableExports = null;
                         }
index 20cf872..d838c14 100644 (file)
@@ -4,7 +4,6 @@
 
 using System.Collections.Generic;
 using System.ComponentModel;
-using System.Linq;
 
 namespace System.Diagnostics
 {
@@ -23,9 +22,9 @@ namespace System.Diagnostics
                 if (IsSelfOrDescendantOf(GetCurrentProcess()))
                     throw new InvalidOperationException(SR.KillEntireProcessTree_DisallowedBecauseTreeContainsCallingProcess);
 
-                IEnumerable<Exception> result = KillTree();
+                List<Exception>? result = KillTree();
 
-                if (result.Any())
+                if (result != null && result.Count != 0)
                     throw new AggregateException(SR.KillEntireProcessTree_TerminationIncomplete, result);
             }
         }
index 889f06a..129963c 100644 (file)
@@ -5,10 +5,7 @@
 using Microsoft.Win32.SafeHandles;
 using System.Collections.Generic;
 using System.ComponentModel;
-using System.Globalization;
 using System.IO;
-using System.Linq;
-using System.Runtime.InteropServices;
 using System.Security;
 using System.Text;
 using System.Threading;
@@ -86,11 +83,11 @@ namespace System.Diagnostics
         private bool GetHasExited(bool refresh)
             => GetWaitState().GetExited(out _, refresh);
 
-        private IEnumerable<Exception> KillTree()
+        private List<Exception>? KillTree()
         {
             List<Exception>? exceptions = null;
             KillTree(ref exceptions);
-            return exceptions ?? Enumerable.Empty<Exception>();
+            return exceptions;
         }
 
         private void KillTree(ref List<Exception>? exceptions)
@@ -111,7 +108,7 @@ namespace System.Diagnostics
                 // Ignore 'process no longer exists' error.
                 if (error != Interop.Error.ESRCH)
                 {
-                    AddException(ref exceptions, new Win32Exception());
+                    (exceptions ??= new List<Exception>()).Add(new Win32Exception());
                 }
                 return;
             }
@@ -125,7 +122,7 @@ namespace System.Diagnostics
                 // Ignore 'process no longer exists' error.
                 if (error != Interop.Error.ESRCH)
                 {
-                    AddException(ref exceptions, new Win32Exception());
+                    (exceptions ??= new List<Exception>()).Add(new Win32Exception());
                 }
             }
 
@@ -134,15 +131,6 @@ namespace System.Diagnostics
                 childProcess.KillTree(ref exceptions);
                 childProcess.Dispose();
             }
-
-            void AddException(ref List<Exception>? list, Exception e)
-            {
-                if (list == null)
-                {
-                    list = new List<Exception>();
-                }
-                list.Add(e);
-            }
         }
 
         /// <summary>Discards any information about the associated process.</summary>
index 565b02e..5ed1aa2 100644 (file)
@@ -4,7 +4,6 @@
 
 using System.Collections.Generic;
 using System.ComponentModel;
-using System.Linq;
 using System.Runtime.InteropServices;
 using System.Text;
 using System.Threading;
@@ -365,7 +364,7 @@ namespace System.Diagnostics
             Id == process.Id
             && StartTime == process.StartTime;
 
-        private IEnumerable<Exception> KillTree()
+        private List<Exception>? KillTree()
         {
             // The process's structures will be preserved as long as a handle is held pointing to them, even if the process exits or
             // is terminated. A handle is held here to ensure a stable reference to the process during execution.
@@ -373,17 +372,17 @@ namespace System.Diagnostics
             {
                 // If the process has exited, the handle is invalid.
                 if (handle.IsInvalid)
-                    return Enumerable.Empty<Exception>();
+                    return null;
 
                 return KillTree(handle);
             }
         }
 
-        private IEnumerable<Exception> KillTree(SafeProcessHandle handle)
+        private List<Exception>? KillTree(SafeProcessHandle handle)
         {
             Debug.Assert(!handle.IsInvalid);
 
-            List<Exception> exceptions = new List<Exception>();
+            List<Exception>? exceptions = null;
 
             try
             {
@@ -394,16 +393,19 @@ namespace System.Diagnostics
             }
             catch (Win32Exception e)
             {
-                exceptions.Add(e);
+                (exceptions ??= new List<Exception>()).Add(e);
             }
 
-            IReadOnlyList<(Process Process, SafeProcessHandle Handle)> children = GetProcessHandlePairs(p => SafePredicateTest(() => IsParentOf(p)));
+            List<(Process Process, SafeProcessHandle Handle)> children = GetProcessHandlePairs(p => SafePredicateTest(() => IsParentOf(p)));
             try
             {
                 foreach ((Process Process, SafeProcessHandle Handle) child in children)
                 {
-                    IEnumerable<Exception> exceptionsFromChild = child.Process.KillTree(child.Handle);
-                    exceptions.AddRange(exceptionsFromChild);
+                    List<Exception>? exceptionsFromChild = child.Process.KillTree(child.Handle);
+                    if (exceptionsFromChild != null)
+                    {
+                        (exceptions ??= new List<Exception>()).AddRange(exceptionsFromChild);
+                    }
                 }
             }
             finally
@@ -418,12 +420,28 @@ namespace System.Diagnostics
             return exceptions;
         }
 
-        private IReadOnlyList<(Process Process, SafeProcessHandle Handle)> GetProcessHandlePairs(Func<Process, bool> predicate)
+        private List<(Process Process, SafeProcessHandle Handle)> GetProcessHandlePairs(Func<Process, bool> predicate)
         {
-            return GetProcesses()
-                .Select(p => (Process: p, Handle: SafeGetHandle(p)))
-                .Where(p => !p.Handle.IsInvalid && predicate(p.Process))
-                .ToList();
+            var results = new List<(Process Process, SafeProcessHandle Handle)>();
+
+            foreach (Process p in GetProcesses())
+            {
+                SafeProcessHandle h = SafeGetHandle(p);
+                if (!h.IsInvalid)
+                {
+                    if (predicate(p))
+                    {
+                        results.Add((p, h));
+                    }
+                    else
+                    {
+                        p.Dispose();
+                        h.Dispose();
+                    }
+                }
+            }
+
+            return results;
 
             static SafeProcessHandle SafeGetHandle(Process process)
             {
index ff2a2ef..d2658af 100644 (file)
@@ -1040,7 +1040,7 @@ namespace System.Linq.Expressions
 
                     return new ScopeWithType(variables, expressions, type);
                 }
-                Expression last = expressions.Last();
+                Expression last = expressions[^1];
                 if (type != typeof(void))
                 {
                     if (!TypeUtils.AreReferenceAssignable(type, last.Type))
index 47a95d2..e38eadc 100644 (file)
@@ -551,7 +551,7 @@ namespace System.Linq.Expressions.Compiler
                     // explicit guard
                     Label secondHalf = _ilg.DefineLabel();
                     _ilg.Emit(OpCodes.Ldloc, info.Value);
-                    EmitConstant(buckets[mid - 1].Last().Constant);
+                    EmitConstant(buckets[mid - 1][^1].Constant);
                     _ilg.Emit(info.IsUnsigned ? OpCodes.Bgt_Un : OpCodes.Bgt, secondHalf);
                     EmitSwitchBuckets(info, buckets, first, mid - 1);
                     _ilg.MarkLabel(secondHalf);
@@ -582,7 +582,7 @@ namespace System.Linq.Expressions.Compiler
             {
                 after = _ilg.DefineLabel();
                 _ilg.Emit(OpCodes.Ldloc, info.Value);
-                EmitConstant(bucket.Last().Constant);
+                EmitConstant(bucket[^1].Constant);
                 _ilg.Emit(info.IsUnsigned ? OpCodes.Bgt_Un : OpCodes.Bgt, after.Value);
                 _ilg.Emit(OpCodes.Ldloc, info.Value);
                 EmitConstant(bucket[0].Constant);
index d261a94..8b6a13d 100644 (file)
@@ -67,7 +67,7 @@ namespace System.Net
             // Current cookie doesn't contain any attributes.
             if (!singleValue.Contains(';')) return false;
 
-            string lastElement = singleValue.Split(';').Last();
+            string lastElement = singleValue.Split(';')[^1];
             bool noComma = !lastElement.Contains(',');
 
             string lastAttribute = lastElement.Split('=')[0].Trim();