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()); } //[Test] public void TestWithReflectionBaking() { Log.Trace("Average with baking: {0:0.000}", Run()); } double Run() { Container.Bind().FromInstance(new Test0()); // Do not include initial reflection costs Container.Instantiate(); Container.Instantiate(); var measurements = new List(); for (int k = 0; k < 10; k++) { var stopwatch = new Stopwatch(); stopwatch.Start(); for (int i = 0; i < 10000; i++) { Container.Instantiate(); } 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; } } } }