From: Stephen Toub Date: Wed, 18 Nov 2020 17:13:45 +0000 (-0500) Subject: Remove most LINQ usage from Microsoft.Extensions.Configuration (#44825) X-Git-Tag: submit/tizen/20210909.063632~4552 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=57c14a2d86b739fb135da5a0e5c65da38dafe552;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Remove most LINQ usage from Microsoft.Extensions.Configuration (#44825) Resulting in several hundred Func, IEnumerable, set, and string allocations at startup. --- diff --git a/src/libraries/Microsoft.Extensions.Configuration/src/ChainedConfigurationProvider.cs b/src/libraries/Microsoft.Extensions.Configuration/src/ChainedConfigurationProvider.cs index 4460595..a240f3d 100644 --- a/src/libraries/Microsoft.Extensions.Configuration/src/ChainedConfigurationProvider.cs +++ b/src/libraries/Microsoft.Extensions.Configuration/src/ChainedConfigurationProvider.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Linq; using Microsoft.Extensions.Primitives; namespace Microsoft.Extensions.Configuration @@ -78,11 +77,14 @@ namespace Microsoft.Extensions.Configuration string parentPath) { IConfiguration section = parentPath == null ? _config : _config.GetSection(parentPath); - IEnumerable children = section.GetChildren(); var keys = new List(); - keys.AddRange(children.Select(c => c.Key)); - return keys.Concat(earlierKeys) - .OrderBy(k => k, ConfigurationKeyComparer.Instance); + foreach (IConfigurationSection child in section.GetChildren()) + { + keys.Add(child.Key); + } + keys.AddRange(earlierKeys); + keys.Sort(ConfigurationKeyComparer.Comparison); + return keys; } /// diff --git a/src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationKeyComparer.cs b/src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationKeyComparer.cs index b0abce1..b5dc31f 100644 --- a/src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationKeyComparer.cs +++ b/src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationKeyComparer.cs @@ -18,6 +18,9 @@ namespace Microsoft.Extensions.Configuration /// public static ConfigurationKeyComparer Instance { get; } = new ConfigurationKeyComparer(); + /// A comparer delegate with the default instance. + internal static Comparison Comparison { get; } = Instance.Compare; + /// /// Compares two strings. /// diff --git a/src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationProvider.cs b/src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationProvider.cs index 15927fe..e337bd3 100644 --- a/src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationProvider.cs +++ b/src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationProvider.cs @@ -3,7 +3,7 @@ using System; using System.Collections.Generic; -using System.Linq; +using System.Diagnostics; using System.Threading; using Microsoft.Extensions.Primitives; @@ -62,13 +62,35 @@ namespace Microsoft.Extensions.Configuration IEnumerable earlierKeys, string parentPath) { - string prefix = parentPath == null ? string.Empty : parentPath + ConfigurationPath.KeyDelimiter; + var results = new List(); - return Data - .Where(kv => kv.Key.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) - .Select(kv => Segment(kv.Key, prefix.Length)) - .Concat(earlierKeys) - .OrderBy(k => k, ConfigurationKeyComparer.Instance); + if (parentPath is null) + { + foreach (KeyValuePair kv in Data) + { + results.Add(Segment(kv.Key, 0)); + } + } + else + { + Debug.Assert(ConfigurationPath.KeyDelimiter == ":"); + + foreach (KeyValuePair kv in Data) + { + if (kv.Key.Length > parentPath.Length && + kv.Key.StartsWith(parentPath, StringComparison.OrdinalIgnoreCase) && + kv.Key[parentPath.Length] == ':') + { + results.Add(Segment(kv.Key, parentPath.Length + 1)); + } + } + } + + results.AddRange(earlierKeys); + + results.Sort(ConfigurationKeyComparer.Comparison); + + return results; } private static string Segment(string key, int prefixLength) diff --git a/src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationRoot.cs b/src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationRoot.cs index bff21d5..455efdb 100644 --- a/src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationRoot.cs +++ b/src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationRoot.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Threading; using Microsoft.Extensions.Primitives; @@ -66,7 +65,7 @@ namespace Microsoft.Extensions.Configuration } set { - if (!_providers.Any()) + if (_providers.Count == 0) { throw new InvalidOperationException(SR.Error_NoSources); }