I'm trying to improve the performance of our application. We have a lot of Activator.CreateInstance calls that are causing some grief.
We instantiate a lot of classes based on an interface (ITabDocument) and after looking around I thought of using this code:
The code is no better (infact marginally slower) than using the Activator.CreateInstance code we had.
public static Func<T> CreateInstance<T>(Type objType) where T : class, new() { var dynMethod = new DynamicMethod("DM$OBJ_FACTORY_" + objType.Name, objType, null, objType); ILGenerator ilGen = dynMethod.GetILGenerator(); ilGen.Emit(OpCodes.Newobj, objType.GetConstructor(Type.EmptyTypes)); ilGen.Emit(OpCodes.Ret); return (Func<T>)dynMethod.CreateDelegate(typeof(Func<T>)); }
I'm wondering why this is, all I'm doing is:
ITabDocument document = CreateInstance<ITabDocument>(Type.GetType("[Company].Something"));
Is there a better way of creating objects which would assist with the above? Its a little hard when you're not sure of the concrete type.
The Activator. CreateInstance method creates an instance of a type defined in an assembly by invoking the constructor that best matches the specified arguments. If no arguments are specified then the constructor that takes no parameters, that is, the default constructor, is invoked.
Activator Class in . NET 4.0. Contains methods to create types of objects locally or remotely, or obtain references to existing remote objects.
I did some benchmarking between these (I would write down the bare minimum details):
public static T Instance() //~1800 ms { return new T(); } public static T Instance() //~1800 ms { return new Activator.CreateInstance<T>(); } public static readonly Func<T> Instance = () => new T(); //~1800 ms public static readonly Func<T> Instance = () => Activator.CreateInstance<T>(); //~1800 ms //works for types with no default constructor as well public static readonly Func<T> Instance = () => (T)FormatterServices.GetUninitializedObject(typeof(T)); //~2000 ms public static readonly Func<T> Instance = Expression.Lambda<Func<T>>(Expression.New(typeof(T))).Compile(); //~50 ms for classes and ~100 ms for structs
As CD says compiled expression is the fastest, and by a big margin. All the methods except (T)FormatterServices.GetUninitializedObject(typeof(T))
work only for types with default constructor.
And caching the compiled resultant delegate is trivial when you have a static class per generic type. Like:
public static class New<T> where T : new() { public static readonly Func<T> Instance = Expression.Lambda<Func<T>> ( Expression.New(typeof(T)) ).Compile(); }
Note the new
constraint. Call anything
MyType me = New<MyType>.Instance();
Except for the first time the class is being loaded in memory, the execution is going to be fastest.
To have a class that handles both types with default constructor and without, I took a hybrid approach, from here:
public static class New<T> { public static readonly Func<T> Instance = Creator(); static Func<T> Creator() { Type t = typeof(T); if (t == typeof(string)) return Expression.Lambda<Func<T>>(Expression.Constant(string.Empty)).Compile(); if (t.HasDefaultConstructor()) return Expression.Lambda<Func<T>>(Expression.New(t)).Compile(); return () => (T)FormatterServices.GetUninitializedObject(t); } } public static bool HasDefaultConstructor(this Type t) { return t.IsValueType || t.GetConstructor(Type.EmptyTypes) != null; }
Will handle value types too in an efficient manner.
Note that (T)FormatterServices.GetUninitializedObject(t)
will fail for string
. Hence special handling for string is in place to return empty string.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With