Skip to content

Commit 8b0f605

Browse files
committed
Optimization. Saved 8 bytes of memory per InstanceProducer. #956
1 parent 48ef4b2 commit 8b0f605

File tree

2 files changed

+10
-11
lines changed

2 files changed

+10
-11
lines changed

src/SimpleInjector/InstanceProducer.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ internal InstanceProducer(Type serviceType, Registration registration, bool regi
107107

108108
this.ServiceType = serviceType;
109109
this.Registration = registration;
110-
this.validator = new CyclicDependencyValidator(this);
110+
this.validator = new CyclicDependencyValidator();
111111

112112
this.lazyExpression = new LazyEx<Expression>(this.BuildExpressionInternal);
113113

@@ -658,7 +658,7 @@ private object BuildAndReplaceInstanceCreatorAndCreateFirstInstance()
658658
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
659659
private void CheckForCyclicDependencies()
660660
{
661-
this.validator?.Check();
661+
this.validator?.Check(this);
662662
}
663663

664664
// This method will be inlined by the JIT.

src/SimpleInjector/Internals/CyclicDependencyValidator.cs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ namespace SimpleInjector.Internals
2121
/// </remarks>
2222
internal sealed class CyclicDependencyValidator
2323
{
24-
private readonly InstanceProducer producer;
25-
2624
// If needed, we can do an extra optimization, which is to have an extra int field for the first
2725
// entered thread. This prevents the list from having to be newed in most cases, as typically there
2826
// is only on thread entering at the same time. This does complicate the code of this class though.
@@ -31,20 +29,21 @@ internal sealed class CyclicDependencyValidator
3129
// path, however, is somethings we prevent at all costs.
3230
private List<int>? enteredThreads;
3331

34-
internal CyclicDependencyValidator(InstanceProducer producer)
35-
{
36-
this.producer = producer;
37-
}
38-
3932
// Checks whether this is a recursive call (and thus a cyclic dependency) and throw in that case.
40-
internal void Check()
33+
// MEMORY: By passing the instance producer in through this method instead of through the ctor,
34+
// this class becomes 8 bytes smaller (on 64 bits) and results in less memory used. This is
35+
// important, because every InstanceProducer gets its own validator and 95% of all validators
36+
// stay in memory.
37+
// TODO: We can reduce an extra 8 bytes of memory per InstanceProducer by merging this class into
38+
// the InstanceProducer itself.
39+
internal void Check(InstanceProducer producer)
4140
{
4241
lock (this)
4342
{
4443
if (this.IsCurrentThreadReentering())
4544
{
4645
throw new CyclicDependencyException(
47-
this.producer, this.producer.Registration.ImplementationType);
46+
producer, producer.Registration.ImplementationType);
4847
}
4948

5049
this.MarkCurrentThreadAsEntering();

0 commit comments

Comments
 (0)