Skip to content

Commit

Permalink
Improve performance registering services comparing to existing servic…
Browse files Browse the repository at this point in the history
…es (#618)
  • Loading branch information
sqeezy authored Aug 14, 2022
1 parent eb5c0c2 commit c493ef6
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Unreleased

- Add fast lookup to check for already registered types. (@sqeezy, #618)
- Change target framework from .NET Standard 1.6 to 2.0 (@generik0, #572)

Bugfixes:
Expand Down
8 changes: 7 additions & 1 deletion src/Castle.Windsor/Core/ComponentModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public sealed class ComponentModel : GraphNode

[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private readonly List<Type> services = new List<Type>(4);
private readonly HashSet<Type> servicesLookup = new HashSet<Type>();

[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private ComponentName componentName;
Expand Down Expand Up @@ -331,6 +332,11 @@ public IEnumerable<Type> Services
{
get { return services; }
}

internal HashSet<Type> ServicesLookup
{
get { return servicesLookup; }
}

[DebuggerBrowsable(DebuggerBrowsableState.Never)]
internal ParameterModelCollection ParametersInternal
Expand Down Expand Up @@ -378,7 +384,7 @@ public void AddService(Type type)
type));
}

ComponentServicesUtil.AddService(services, type);
ComponentServicesUtil.AddService(services, servicesLookup, type);
}

/// <summary>
Expand Down
8 changes: 6 additions & 2 deletions src/Castle.Windsor/Core/Internal/ComponentServicesUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,16 @@ public class ComponentServicesUtil
{
private static readonly TypeByInheritanceDepthMostSpecificFirstComparer comparer = new TypeByInheritanceDepthMostSpecificFirstComparer();

public static void AddService(IList<Type> existingServices, Type newService)
public static void AddService(IList<Type> existingServices, HashSet<Type> lookup, Type newService)
{
if (existingServices.Contains(newService))
if (lookup.Contains(newService))
{
return;
}
if (newService.GetTypeInfo().IsInterface)
{
existingServices.Add(newService);
lookup.Add(newService);
return;
}
if (newService.GetTypeInfo().IsClass == false)
Expand All @@ -44,18 +45,21 @@ public static void AddService(IList<Type> existingServices, Type newService)
if (existingServices[i].GetTypeInfo().IsInterface)
{
existingServices.Insert(i, newService);
lookup.Add(newService);
}
var result = comparer.Compare(newService, existingServices[i]);
if (result < 0)
{
existingServices.Insert(i, newService);
lookup.Add(newService);
return;
}
if (result == 0)
{
return;
}
}
lookup.Add(newService);
existingServices.Add(newService);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Castle.Windsor/MicroKernel/Handlers/AbstractHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ public object Resolve(CreationContext context)

public virtual bool Supports(Type service)
{
return ComponentModel.Services.Contains(service);
return ComponentModel.ServicesLookup.Contains(service);
}

public virtual bool SupportsAssignable(Type service)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public class ComponentRegistration<TService> : IRegistration
{
private readonly List<IComponentModelDescriptor> descriptors = new List<IComponentModelDescriptor>();
private readonly List<Type> potentialServices = new List<Type>();
private readonly HashSet<Type> potentialServicesLookup = new HashSet<Type>();

private bool ifComponentRegisteredIgnore;
private Type implementation;
Expand Down Expand Up @@ -473,7 +474,7 @@ public ComponentRegistration<TService> Forward(IEnumerable<Type> types)
{
foreach (var type in types)
{
ComponentServicesUtil.AddService(potentialServices, type);
ComponentServicesUtil.AddService(potentialServices, potentialServicesLookup, type);
}
return this;
}
Expand Down

0 comments on commit c493ef6

Please sign in to comment.