性能反复创建实例在运行时
最好的办法是编译表达式:
static readonly Func<X> YCreator = Expression.Lambda<Func<X>>(
Expression.New(typeof(Y).GetConstructor(Type.EmptyTypes))
).Compile();
X x = YCreator();
统计(2012年):
Iterations: 5000000
00:00:00.8481762, Activator.CreateInstance(string, string)
00:00:00.8416930, Activator.CreateInstance(type)
00:00:06.6236752, ConstructorInfo.Invoke
00:00:00.1776255, Compiled expression
00:00:00.0462197, new
统计(2015,.NET 4.5,64):
Iterations: 5000000
00:00:00.2659981, Activator.CreateInstance(string, string)
00:00:00.2603770, Activator.CreateInstance(type)
00:00:00.7478936, ConstructorInfo.Invoke
00:00:00.0700757, Compiled expression
00:00:00.0286710, new
统计信息(2015,.net 4.5,x86):
Iterations: 5000000
00:00:00.3541501, Activator.CreateInstance(string, string)
00:00:00.3686861, Activator.CreateInstance(type)
00:00:00.9492354, ConstructorInfo.Invoke
00:00:00.0719072, Compiled expression
00:00:00.0229387, new
全码:
public static X CreateY_New()
{
return new Y();
}
public static X CreateY_CreateInstance()
{
return (X)Activator.CreateInstance(typeof(Y));
}
public static X CreateY_CreateInstance_String()
{
return (X)Activator.CreateInstance("Program", "Y").Unwrap();
}
static readonly System.Reflection.ConstructorInfo YConstructor =
typeof(Y).GetConstructor(Type.EmptyTypes);
static readonly object[] Empty = new object[] { };
public static X CreateY_Invoke()
{
return (X)YConstructor.Invoke(Empty);
}
static readonly Func<X> YCreator = Expression.Lambda<Func<X>>(
Expression.New(typeof(Y).GetConstructor(Type.EmptyTypes))
).Compile();
public static X CreateY_CompiledExpression()
{
return YCreator();
}
static void Main(string[] args)
{
const int iterations = 5000000;
Console.WriteLine("Iterations: {0}", iterations);
foreach (var creatorInfo in new []
{
new {Name = "Activator.CreateInstance(string, string)", Creator = (Func<X>)CreateY_CreateInstance},
new {Name = "Activator.CreateInstance(type)", Creator = (Func<X>)CreateY_CreateInstance},
new {Name = "ConstructorInfo.Invoke", Creator = (Func<X>)CreateY_Invoke},
new {Name = "Compiled expression", Creator = (Func<X>)CreateY_CompiledExpression},
new {Name = "new", Creator = (Func<X>)CreateY_New},
})
{
var creator = creatorInfo.Creator;
var sum = 0;
for (var i = 0; i < 1000; i++)
sum += creator().Z;
var stopwatch = new Stopwatch();
stopwatch.Start();
for (var i = 0; i < iterations; ++i)
{
var x = creator();
sum += x.Z;
}
stopwatch.Stop();
Console.WriteLine("{0}, {1}", stopwatch.Elapsed, creatorInfo.Name);
}
}
public class X
{
public X() { }
public X(int z) { this.Z = z; }
public int Z;
}
public class Y : X { }
最佳可能是[表达式树IMO(http://stackoverflow.com/questions/6582259/fast-creation-of-objects-instead-of-activator- createinstancetype) – nawfal 2013-06-12 21:04:31