353 lines
11 KiB
C#
353 lines
11 KiB
C#
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using ModestTree;
|
|
using Zenject.Internal;
|
|
|
|
#pragma warning disable 414
|
|
|
|
namespace Zenject.Tests.Injection
|
|
{
|
|
//[TestFixture]
|
|
// Conclusion here is that the compiled expressions are basically identical to reflection
|
|
// baking during the instantiate (though there are wins during initialization)
|
|
// When compiled expressions are not used such as IL2CPP however there is a noticable
|
|
// improvement of maybe 15-20% for instantiate
|
|
public class TestInstantiateApproaches : ZenjectUnitTestFixture
|
|
{
|
|
//[Test]
|
|
public void TestWithoutReflectionBaking()
|
|
{
|
|
Log.Trace("Average without baking: {0:0.000}", Run<FooDerivedNoBaking>());
|
|
}
|
|
|
|
//[Test]
|
|
public void TestWithReflectionBaking()
|
|
{
|
|
Log.Trace("Average with baking: {0:0.000}", Run<FooDerivedBaked>());
|
|
}
|
|
|
|
double Run<T>()
|
|
{
|
|
Container.Bind<Test0>().FromInstance(new Test0());
|
|
|
|
// Do not include initial reflection costs
|
|
Container.Instantiate<T>();
|
|
Container.Instantiate<T>();
|
|
|
|
var measurements = new List<double>();
|
|
|
|
for (int k = 0; k < 10; k++)
|
|
{
|
|
var stopwatch = new Stopwatch();
|
|
stopwatch.Start();
|
|
for (int i = 0; i < 10000; i++)
|
|
{
|
|
Container.Instantiate<T>();
|
|
}
|
|
stopwatch.Stop();
|
|
measurements.Add(stopwatch.Elapsed.TotalSeconds);
|
|
}
|
|
|
|
return measurements.Average();
|
|
}
|
|
|
|
[NoReflectionBaking]
|
|
class Test0
|
|
{
|
|
}
|
|
|
|
[NoReflectionBaking]
|
|
abstract class FooBaseBaked
|
|
{
|
|
[Inject]
|
|
public Test0 BaseFieldPublic = null;
|
|
|
|
[Inject]
|
|
Test0 BaseFieldPrivate = null;
|
|
|
|
[Inject]
|
|
protected Test0 BaseFieldProtected = null;
|
|
|
|
[Inject]
|
|
public Test0 BasePropertyPublic
|
|
{
|
|
get; set;
|
|
}
|
|
|
|
[Inject]
|
|
Test0 BasePropertyPrivate
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
[Inject]
|
|
protected Test0 BasePropertyProtected
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
[Inject]
|
|
public void PostInjectBase()
|
|
{
|
|
DidPostInjectBase = true;
|
|
}
|
|
|
|
public bool DidPostInjectBase
|
|
{
|
|
get; private set;
|
|
}
|
|
|
|
private static void __zenFieldSetter0(object P_0, object P_1)
|
|
{
|
|
((FooBaseBaked)P_0).BaseFieldPublic = (Test0)P_1;
|
|
}
|
|
|
|
private static void __zenFieldSetter1(object P_0, object P_1)
|
|
{
|
|
((FooBaseBaked)P_0).BaseFieldPrivate = (Test0)P_1;
|
|
}
|
|
|
|
private static void __zenFieldSetter2(object P_0, object P_1)
|
|
{
|
|
((FooBaseBaked)P_0).BaseFieldProtected = (Test0)P_1;
|
|
}
|
|
|
|
private static void __zenPropertySetter0(object P_0, object P_1)
|
|
{
|
|
((FooBaseBaked)P_0).BasePropertyPublic = (Test0)P_1;
|
|
}
|
|
|
|
private static void __zenPropertySetter1(object P_0, object P_1)
|
|
{
|
|
((FooBaseBaked)P_0).BasePropertyPrivate = (Test0)P_1;
|
|
}
|
|
|
|
private static void __zenPropertySetter2(object P_0, object P_1)
|
|
{
|
|
((FooBaseBaked)P_0).BasePropertyProtected = (Test0)P_1;
|
|
}
|
|
|
|
private static void __zenInjectMethod0(object P_0, object[] P_1)
|
|
{
|
|
((FooBaseBaked)P_0).PostInjectBase();
|
|
}
|
|
|
|
[Preserve]
|
|
private static InjectTypeInfo CreateInjectTypeInfo()
|
|
{
|
|
return new InjectTypeInfo(typeof(FooBaseBaked), new InjectTypeInfo.InjectConstructorInfo(null, new InjectableInfo[0]), new InjectTypeInfo.InjectMethodInfo[1]
|
|
{
|
|
new InjectTypeInfo.InjectMethodInfo(__zenInjectMethod0, new InjectableInfo[0], "PostInjectBase")
|
|
}, new InjectTypeInfo.InjectMemberInfo[6]
|
|
{
|
|
new InjectTypeInfo.InjectMemberInfo(__zenFieldSetter0, new InjectableInfo(false, null, "BaseFieldPublic", typeof(Test0), null, 0)),
|
|
new InjectTypeInfo.InjectMemberInfo(__zenFieldSetter1, new InjectableInfo(false, null, "BaseFieldPrivate", typeof(Test0), null, 0)),
|
|
new InjectTypeInfo.InjectMemberInfo(__zenFieldSetter2, new InjectableInfo(false, null, "BaseFieldProtected", typeof(Test0), null, 0)),
|
|
new InjectTypeInfo.InjectMemberInfo(__zenPropertySetter0, new InjectableInfo(false, null, "BasePropertyPublic", typeof(Test0), null, 0)),
|
|
new InjectTypeInfo.InjectMemberInfo(__zenPropertySetter1, new InjectableInfo(false, null, "BasePropertyPrivate", typeof(Test0), null, 0)),
|
|
new InjectTypeInfo.InjectMemberInfo(__zenPropertySetter2, new InjectableInfo(false, null, "BasePropertyProtected", typeof(Test0), null, 0))
|
|
});
|
|
}
|
|
}
|
|
|
|
[NoReflectionBaking]
|
|
class FooDerivedBaked : FooBaseBaked
|
|
{
|
|
public Test0 ConstructorParam = null;
|
|
|
|
// Instance
|
|
public FooDerivedBaked(Test0 param)
|
|
{
|
|
ConstructorParam = param;
|
|
}
|
|
|
|
[Inject]
|
|
public void PostInject()
|
|
{
|
|
}
|
|
|
|
[Inject]
|
|
public Test0 DerivedFieldPublic = null;
|
|
|
|
[Inject]
|
|
Test0 DerivedFieldPrivate = null;
|
|
|
|
[Inject]
|
|
protected Test0 DerivedFieldProtected = null;
|
|
|
|
[Inject]
|
|
public Test0 DerivedPropertyPublic
|
|
{
|
|
get; set;
|
|
}
|
|
|
|
[Inject]
|
|
Test0 DerivedPropertyPrivate
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
[Inject]
|
|
protected Test0 DerivedPropertyProtected
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
private static object __zenCreate(object[] P_0)
|
|
{
|
|
return new FooDerivedBaked((Test0)P_0[0]);
|
|
}
|
|
|
|
private static void __zenFieldSetter0(object P_0, object P_1)
|
|
{
|
|
((FooDerivedBaked)P_0).DerivedFieldPublic = (Test0)P_1;
|
|
}
|
|
|
|
private static void __zenFieldSetter1(object P_0, object P_1)
|
|
{
|
|
((FooDerivedBaked)P_0).DerivedFieldPrivate = (Test0)P_1;
|
|
}
|
|
|
|
private static void __zenFieldSetter2(object P_0, object P_1)
|
|
{
|
|
((FooDerivedBaked)P_0).DerivedFieldProtected = (Test0)P_1;
|
|
}
|
|
|
|
private static void __zenPropertySetter0(object P_0, object P_1)
|
|
{
|
|
((FooDerivedBaked)P_0).DerivedPropertyPublic = (Test0)P_1;
|
|
}
|
|
|
|
private static void __zenPropertySetter1(object P_0, object P_1)
|
|
{
|
|
((FooDerivedBaked)P_0).DerivedPropertyPrivate = (Test0)P_1;
|
|
}
|
|
|
|
private static void __zenPropertySetter2(object P_0, object P_1)
|
|
{
|
|
((FooDerivedBaked)P_0).DerivedPropertyProtected = (Test0)P_1;
|
|
}
|
|
|
|
private static void __zenInjectMethod0(object P_0, object[] P_1)
|
|
{
|
|
((FooDerivedBaked)P_0).PostInject();
|
|
}
|
|
|
|
[Preserve]
|
|
private static InjectTypeInfo CreateInjectTypeInfo()
|
|
{
|
|
return new InjectTypeInfo(typeof(FooDerivedBaked), new InjectTypeInfo.InjectConstructorInfo(__zenCreate, new InjectableInfo[1]
|
|
{
|
|
new InjectableInfo(false, null, "param", typeof(Test0), null, 0)
|
|
}), new InjectTypeInfo.InjectMethodInfo[1]
|
|
{
|
|
new InjectTypeInfo.InjectMethodInfo(__zenInjectMethod0, new InjectableInfo[0], "PostInject")
|
|
}, new InjectTypeInfo.InjectMemberInfo[6]
|
|
{
|
|
new InjectTypeInfo.InjectMemberInfo(__zenFieldSetter0, new InjectableInfo(false, null, "DerivedFieldPublic", typeof(Test0), null, 0)),
|
|
new InjectTypeInfo.InjectMemberInfo(__zenFieldSetter1, new InjectableInfo(false, null, "DerivedFieldPrivate", typeof(Test0), null, 0)),
|
|
new InjectTypeInfo.InjectMemberInfo(__zenFieldSetter2, new InjectableInfo(false, null, "DerivedFieldProtected", typeof(Test0), null, 0)),
|
|
new InjectTypeInfo.InjectMemberInfo(__zenPropertySetter0, new InjectableInfo(false, null, "DerivedPropertyPublic", typeof(Test0), null, 0)),
|
|
new InjectTypeInfo.InjectMemberInfo(__zenPropertySetter1, new InjectableInfo(false, null, "DerivedPropertyPrivate", typeof(Test0), null, 0)),
|
|
new InjectTypeInfo.InjectMemberInfo(__zenPropertySetter2, new InjectableInfo(false, null, "DerivedPropertyProtected", typeof(Test0), null, 0))
|
|
});
|
|
}
|
|
}
|
|
|
|
[NoReflectionBaking]
|
|
abstract class FooBaseNoBaking
|
|
{
|
|
[Inject]
|
|
public Test0 BaseFieldPublic = null;
|
|
|
|
[Inject]
|
|
Test0 BaseFieldPrivate = null;
|
|
|
|
[Inject]
|
|
protected Test0 BaseFieldProtected = null;
|
|
|
|
[Inject]
|
|
public Test0 BasePropertyPublic
|
|
{
|
|
get; set;
|
|
}
|
|
|
|
[Inject]
|
|
Test0 BasePropertyPrivate
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
[Inject]
|
|
protected Test0 BasePropertyProtected
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
[Inject]
|
|
public void PostInjectBase()
|
|
{
|
|
DidPostInjectBase = true;
|
|
}
|
|
|
|
public bool DidPostInjectBase
|
|
{
|
|
get; private set;
|
|
}
|
|
}
|
|
|
|
[NoReflectionBaking]
|
|
class FooDerivedNoBaking : FooBaseNoBaking
|
|
{
|
|
public Test0 ConstructorParam = null;
|
|
|
|
// Instance
|
|
public FooDerivedNoBaking(Test0 param)
|
|
{
|
|
ConstructorParam = param;
|
|
}
|
|
|
|
[Inject]
|
|
public void PostInject()
|
|
{
|
|
}
|
|
|
|
[Inject]
|
|
public Test0 DerivedFieldPublic = null;
|
|
|
|
[Inject]
|
|
Test0 DerivedFieldPrivate = null;
|
|
|
|
[Inject]
|
|
protected Test0 DerivedFieldProtected = null;
|
|
|
|
[Inject]
|
|
public Test0 DerivedPropertyPublic
|
|
{
|
|
get; set;
|
|
}
|
|
|
|
[Inject]
|
|
Test0 DerivedPropertyPrivate
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
[Inject]
|
|
protected Test0 DerivedPropertyProtected
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
}
|
|
}
|
|
}
|