private Func <object[], object> UpdateConstructors(int maxArgIndex, out int argsCount, out string[] globalArgNames) { MemberWrapper[] args = null; if (maxArgIndex > -1) { args = new MemberWrapper[maxArgIndex + 1]; foreach (PropertyWrapper wrapper in Properties) { if (wrapper.ConstructorArg != -1) { args[wrapper.ConstructorArg] = wrapper; } } foreach (FieldWrapper wrapper in Fields) { if (wrapper.ConstructorArg != -1) { args[wrapper.ConstructorArg] = wrapper; } } } globalArgNames = null; ConstructorInfo bestCtor = null; float bestCtorScore = -1; ParameterInfo[] bestCtorParameterInfos = null; foreach (ConstructorInfo info in Type.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { ParameterInfo[] parameterInfos = null; string[] names = null; float score = TestConstructor(info, args, ref names, ref parameterInfos); if (score > bestCtorScore) { bestCtorScore = score; bestCtor = info; bestCtorParameterInfos = parameterInfos; globalArgNames = names; } } if (bestCtor == null) { if (Type.IsValueType) { argsCount = 0; return(InvocationHelper.CreateConstructorDelegate(Type, null, null)); } throw new SerializationException($"Unable to get best constructor for {Type.FullName}"); } argsCount = bestCtorParameterInfos.Length; return(InvocationHelper.CreateConstructorDelegate(Type, bestCtor, bestCtorParameterInfos)); }
public static object CreateParameterless(Type type) { Func <object> func; if (!typeConstructors.TryGetValue(type, out func)) { func = InvocationHelper.CreateConstructorDelegate(type); typeConstructors.Add(type, func); } return(func()); }
public static void TestPerformance() { Test test = new Test(); PropertyInfo info = typeof(Test).GetProperty("A"); const string TEST = "1"; info.SetValue(test, TEST); Action <object, object> action = InvocationHelper.CreateSetDelegate(typeof(Test), typeof(string), info.SetMethod); MethodInfo method = info.SetMethod; action(test, TEST); Action <object, object> actionUntyped = SetUntyped; Action <Test, string> actionTyped = SetUntyped; Action <Test, string> actionLambdaTyped = (target, arg) => target.A = arg; Action <object, object> actionLambdaUntyped = (target, arg) => ((Test)target).A = (string)arg; Action <Test, string> actionDelegate = (Action <Test, string>)Delegate.CreateDelegate(typeof(Action <Test, string>), method); Func <object> actionCreateLambda = CreateConstructorDelegate(typeof(Test)); Func <object> actionCreateEmit = InvocationHelper.CreateConstructorDelegate(typeof(Test)); ConstructorInfo ctor = typeof(Test).GetConstructor(Type.EmptyTypes); ConstructorInfo ctorString = typeof(Test).GetConstructor(new Type[] { typeof(string) }); Func <object[], object> actionCreateEmitString = InvocationHelper.CreateConstructorDelegate(typeof(Test), ctorString, ctorString.GetParameters()); Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine("Performance test: Property set..."); Console.ForegroundColor = ConsoleColor.Gray; WriteTestStart("PropertyInfo.SetValue"); Stopwatch stopwatch = Stopwatch.StartNew(); for (int i = 0; i < ITERATIONS; i++) { info.SetValue(test, TEST); } stopwatch.Stop(); WriteTestFinish(stopwatch); WriteTestStart("MethodInfo.Invoke"); stopwatch.Restart(); object[] cache = { TEST }; for (int i = 0; i < ITERATIONS; i++) { method.Invoke(test, cache); } stopwatch.Stop(); WriteTestFinish(stopwatch); WriteTestStart("InvocationHelper.CreateSetDelegate"); stopwatch.Restart(); for (int i = 0; i < ITERATIONS; i++) { action(test, TEST); } stopwatch.Stop(); WriteTestFinish(stopwatch); WriteTestStart("test.A = TEST"); stopwatch.Restart(); for (int i = 0; i < ITERATIONS; i++) { test.A = TEST; } stopwatch.Stop(); WriteTestFinish(stopwatch); WriteTestStart("SetTyped(Test test, string s)"); stopwatch.Restart(); for (int i = 0; i < ITERATIONS; i++) { SetTyped(test, TEST); } stopwatch.Stop(); WriteTestFinish(stopwatch); WriteTestStart("SetUntyped(object test, object s)"); stopwatch.Restart(); for (int i = 0; i < ITERATIONS; i++) { SetUntyped(test, TEST); } stopwatch.Stop(); WriteTestFinish(stopwatch); WriteTestStart("Action<Test, string>"); stopwatch.Restart(); for (int i = 0; i < ITERATIONS; i++) { actionTyped(test, TEST); } stopwatch.Stop(); WriteTestFinish(stopwatch); WriteTestStart("Action<object, object>"); stopwatch.Restart(); for (int i = 0; i < ITERATIONS; i++) { actionUntyped(test, TEST); } stopwatch.Stop(); WriteTestFinish(stopwatch); WriteTestStart("=> target.A = arg"); stopwatch.Restart(); for (int i = 0; i < ITERATIONS; i++) { actionLambdaTyped(test, TEST); } stopwatch.Stop(); WriteTestFinish(stopwatch); WriteTestStart("=> ((Test)target).A = (string)arg"); stopwatch.Restart(); for (int i = 0; i < ITERATIONS; i++) { actionLambdaUntyped(test, TEST); } stopwatch.Stop(); WriteTestFinish(stopwatch); WriteTestStart("Delegate.CreateDelegate"); stopwatch.Restart(); for (int i = 0; i < ITERATIONS; i++) { actionDelegate(test, TEST); } stopwatch.Stop(); WriteTestFinish(stopwatch); WriteTestStart("Delegate.DynamicInvoke"); stopwatch.Restart(); for (int i = 0; i < ITERATIONS; i++) { action.DynamicInvoke(test, TEST); } stopwatch.Stop(); WriteTestFinish(stopwatch); Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine(); Console.WriteLine("Performance test: Object creation..."); Console.ForegroundColor = ConsoleColor.Gray; WriteTestStart("Activator.Create"); stopwatch.Restart(); for (int i = 0; i < ITERATIONS; i++) { Activator.CreateInstance(typeof(Test)); } stopwatch.Stop(); WriteTestFinish(stopwatch); WriteTestStart("CreateConstructorDelegate"); stopwatch.Restart(); for (int i = 0; i < ITERATIONS; i++) { actionCreateEmit(); } stopwatch.Stop(); WriteTestFinish(stopwatch); WriteTestStart("() => new TResult()"); stopwatch.Restart(); for (int i = 0; i < ITERATIONS; i++) { actionCreateLambda(); } stopwatch.Stop(); WriteTestFinish(stopwatch); WriteTestStart("ConstructorInfo.Invoke"); stopwatch.Restart(); for (int i = 0; i < ITERATIONS; i++) { ctor.Invoke(null); } stopwatch.Stop(); WriteTestFinish(stopwatch); WriteTestStart("new Test()"); stopwatch.Restart(); for (int i = 0; i < ITERATIONS; i++) { // ReSharper disable once ObjectCreationAsStatement new Test(); } stopwatch.Stop(); WriteTestFinish(stopwatch); WriteTestStart("Activator.Create (string)"); stopwatch.Restart(); for (int i = 0; i < ITERATIONS; i++) { Activator.CreateInstance(typeof(Test), cache); } stopwatch.Stop(); WriteTestFinish(stopwatch); WriteTestStart("CreateConstructorDelegate(string)"); stopwatch.Restart(); for (int i = 0; i < ITERATIONS; i++) { actionCreateEmitString(cache); } stopwatch.Stop(); WriteTestFinish(stopwatch); WriteTestStart("ConstructorInfo.Invoke(string)"); stopwatch.Restart(); for (int i = 0; i < ITERATIONS; i++) { ctorString.Invoke(cache); } stopwatch.Stop(); WriteTestFinish(stopwatch); WriteTestStart("new Test(string)"); stopwatch.Restart(); for (int i = 0; i < ITERATIONS; i++) { // ReSharper disable once ObjectCreationAsStatement new Test(TEST); } stopwatch.Stop(); WriteTestFinish(stopwatch); Console.WriteLine("-- All done. Press <Enter> to continue."); Console.WriteLine(); }