Skip to content

Commit

Permalink
Reduce allocations in Microsoft.Extensions.Configuration (#88211)
Browse files Browse the repository at this point in the history
Co-authored-by: Günther Foidl <gue@korporal.at>
  • Loading branch information
pentp and gfoidl committed Jun 30, 2023
1 parent e7e9925 commit 7b13ea8
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ public static string Combine(IEnumerable<string> pathSegments)
return path;
}

int lastDelimiterIndex = path.LastIndexOf(KeyDelimiter, StringComparison.OrdinalIgnoreCase);
return lastDelimiterIndex == -1 ? path : path.Substring(lastDelimiterIndex + 1);
int lastDelimiterIndex = path.LastIndexOf(':');
return lastDelimiterIndex < 0 ? path : path.Substring(lastDelimiterIndex + 1);
}

/// <summary>
Expand All @@ -70,8 +70,8 @@ public static string Combine(IEnumerable<string> pathSegments)
return null;
}

int lastDelimiterIndex = path.LastIndexOf(KeyDelimiter, StringComparison.OrdinalIgnoreCase);
return lastDelimiterIndex == -1 ? null : path.Substring(0, lastDelimiterIndex);
int lastDelimiterIndex = path.LastIndexOf(':');
return lastDelimiterIndex < 0 ? null : path.Substring(0, lastDelimiterIndex);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public static class ConfigurationBinder
[RequiresDynamicCode(DynamicCodeWarningMessage)]
[RequiresUnreferencedCode(TrimmingWarningMessage)]
public static T? Get<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>(this IConfiguration configuration)
=> configuration.Get<T>(_ => { });
=> configuration.Get<T>(null);

/// <summary>
/// Attempts to bind the configuration instance to a new instance of type T.
Expand Down Expand Up @@ -71,7 +71,7 @@ public static class ConfigurationBinder
[RequiresDynamicCode(DynamicCodeWarningMessage)]
[RequiresUnreferencedCode(TrimmingWarningMessage)]
public static object? Get(this IConfiguration configuration, Type type)
=> configuration.Get(type, _ => { });
=> configuration.Get(type, null);

/// <summary>
/// Attempts to bind the configuration instance to a new instance of type T.
Expand Down Expand Up @@ -118,7 +118,7 @@ public static void Bind(this IConfiguration configuration, string key, object? i
[RequiresDynamicCode(DynamicCodeWarningMessage)]
[RequiresUnreferencedCode(InstanceGetTypeTrimmingWarningMessage)]
public static void Bind(this IConfiguration configuration, object? instance)
=> configuration.Bind(instance, _ => { });
=> configuration.Bind(instance, null);

/// <summary>
/// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively.
Expand Down Expand Up @@ -220,13 +220,16 @@ private static void BindProperties(object instance, IConfiguration configuration
HashSet<string> propertyNames = new(modelProperties.Select(mp => mp.Name),
StringComparer.OrdinalIgnoreCase);

IEnumerable<IConfigurationSection> configurationSections = configuration.GetChildren();
List<string> missingPropertyNames = configurationSections
.Where(cs => !propertyNames.Contains(cs.Key))
.Select(mp => $"'{mp.Key}'")
.ToList();
List<string>? missingPropertyNames = null;
foreach (IConfigurationSection cs in configuration.GetChildren())
{
if (!propertyNames.Contains(cs.Key))
{
(missingPropertyNames ??= new()).Add($"'{cs.Key}'");
}
}

if (missingPropertyNames.Count > 0)
if (missingPropertyNames != null)
{
throw new InvalidOperationException(SR.Format(SR.Error_MissingConfig,
nameof(options.ErrorOnUnknownConfiguration), nameof(BinderOptions), instance.GetType(),
Expand Down Expand Up @@ -381,7 +384,7 @@ private static void BindInstance(
(interfaceGenericType == typeof(ICollection<>) || interfaceGenericType == typeof(IList<>)))
{
// For ICollection<T> and IList<T> we bind them to mutable List<T> type.
Type genericType = typeof(List<>).MakeGenericType(type.GenericTypeArguments[0]);
Type genericType = typeof(List<>).MakeGenericType(type.GenericTypeArguments);
bindingPoint.SetValue(Activator.CreateInstance(genericType));
}
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ namespace Microsoft.Extensions.Configuration
/// </summary>
public class ConfigurationBuilder : IConfigurationBuilder
{
private readonly List<IConfigurationSource> _sources = new();

/// <summary>
/// Returns the sources used to obtain configuration values.
/// </summary>
public IList<IConfigurationSource> Sources { get; } = new List<IConfigurationSource>();
public IList<IConfigurationSource> Sources => _sources;

/// <summary>
/// Gets a key/value collection that can be used to share data between the <see cref="IConfigurationBuilder"/>
Expand All @@ -31,7 +33,7 @@ public IConfigurationBuilder Add(IConfigurationSource source)
{
ThrowHelper.ThrowIfNull(source);

Sources.Add(source);
_sources.Add(source);
return this;
}

Expand All @@ -43,7 +45,7 @@ public IConfigurationBuilder Add(IConfigurationSource source)
public IConfigurationRoot Build()
{
var providers = new List<IConfigurationProvider>();
foreach (IConfigurationSource source in Sources)
foreach (IConfigurationSource source in _sources)
{
IConfigurationProvider provider = source.Build(this);
providers.Add(provider);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,10 +229,7 @@ public void CopyTo(IConfigurationSource[] array, int arrayIndex)
_sources.CopyTo(array, arrayIndex);
}

public IEnumerator<IConfigurationSource> GetEnumerator()
{
return _sources.GetEnumerator();
}
public List<IConfigurationSource>.Enumerator GetEnumerator() => _sources.GetEnumerator();

public int IndexOf(IConfigurationSource source)
{
Expand All @@ -258,10 +255,9 @@ public void RemoveAt(int index)
_config.ReloadSources();
}

IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

IEnumerator<IConfigurationSource> IEnumerable<IConfigurationSource>.GetEnumerator() => GetEnumerator();
}

private sealed class ConfigurationBuilderProperties : IDictionary<string, object>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ public virtual IEnumerable<string> GetChildKeys(

private static string Segment(string key, int prefixLength)
{
int indexOf = key.IndexOf(ConfigurationPath.KeyDelimiter, prefixLength, StringComparison.OrdinalIgnoreCase);
Debug.Assert(ConfigurationPath.KeyDelimiter == ":");
int indexOf = key.IndexOf(':', prefixLength);
return indexOf < 0 ? key.Substring(prefixLength) : key.Substring(prefixLength, indexOf - prefixLength);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ public string? this[string key]
{
get
{
return _root[ConfigurationPath.Combine(Path, key)];
return _root[Path + ConfigurationPath.KeyDelimiter + key];
}
set
{
_root[ConfigurationPath.Combine(Path, key)] = value;
_root[Path + ConfigurationPath.KeyDelimiter + key] = value;
}
}

Expand All @@ -86,7 +86,7 @@ public string? this[string key]
/// This method will never return <c>null</c>. If no matching sub-section is found with the specified key,
/// an empty <see cref="IConfigurationSection"/> will be returned.
/// </remarks>
public IConfigurationSection GetSection(string key) => _root.GetSection(ConfigurationPath.Combine(Path, key));
public IConfigurationSection GetSection(string key) => _root.GetSection(Path + ConfigurationPath.KeyDelimiter + key);

/// <summary>
/// Gets the immediate descendant configuration sub-sections.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ internal static IEnumerable<IConfigurationSection> GetChildrenImplementation(thi
.Aggregate(Enumerable.Empty<string>(),
(seed, source) => source.GetChildKeys(seed, path))
.Distinct(StringComparer.OrdinalIgnoreCase)
.Select(key => root.GetSection(path == null ? key : ConfigurationPath.Combine(path, key)));
.Select(key => root.GetSection(path == null ? key : path + ConfigurationPath.KeyDelimiter + key));

if (reference is null)
{
Expand Down

0 comments on commit 7b13ea8

Please sign in to comment.