.net System.Activator.CreateInstance(T)的性能问题是否足以阻止我们随意使用它?
.net System.Activator.CreateInstance(T)的性能问题是否足以阻止我们随意使用它?,.net,performance,instantiation,activator,.net,Performance,Instantiation,Activator,System.Activator.CreateInstance(T)方法是否存在性能问题(因为我怀疑它使用反射),足以阻止我们随意使用它?这取决于您的用例。如果您需要非常高的性能并且正在创建许多对象,那么使用Activator.CreateInstance可能会有问题 但在大多数情况下,它将足够快,是一种非常强大的创建对象的方法 事实上,大多数IoC容器/服务定位器/无论您如何称呼它们,都使用此方法来创建您请求的类型的对象 如果您担心性能不够好,那么应该对应用程序进行分析,并测量是否存在瓶颈以及
System.Activator.CreateInstance(T)
方法是否存在性能问题(因为我怀疑它使用反射),足以阻止我们随意使用它?这取决于您的用例。如果您需要非常高的性能并且正在创建许多对象,那么使用Activator.CreateInstance
可能会有问题
但在大多数情况下,它将足够快,是一种非常强大的创建对象的方法
事实上,大多数IoC容器/服务定位器/无论您如何称呼它们,都使用此方法来创建您请求的类型的对象
如果您担心性能不够好,那么应该对应用程序进行分析,并测量是否存在瓶颈以及瓶颈所在。我的猜测是,调用Activator.CreateInstance将不是您的问题。一如既往,回答性能问题的唯一正确方法是实际测量代码 下面是一个示例程序,用于测试:
- Activator.CreateInstance
- 新T()
- 调用调用新T()的委托
是的,两次呼叫之间存在性能差异
(MyClass)Activator.CreateInstance(typeof(MyClass));
及
后者的速度更快。但是速度下降是否足够大取决于你的领域。在90%的情况下,这不是一个问题。还要注意的是,对于值类型,Activator.CreateInstance
由于涉及到
但这里有一个问题:对于泛型类型,它们是相似的newt()
内部调用Activator.CreateInstance()
,后者依次调用。因此,如果您有一个通用方法来创建T
的新实例,那么它应该无关紧要,尽管有new()
约束并调用new T()
更具可读性。以下是Jon Skeet的主题。这是一个C#NET 4.0示例程序,它测试:
- Activator.CreateInstance
- 新T()
- 调用调用新T()的委托
- 通用新()
- Activator.CreateInstance使用泛型
- Activator.CreateInstance使用通用和非默认绑定(例如调用内部构造函数)
Test1-Activator.CreateInstance():8542
Test2-新的T()1082
Test3-委托1214
Test4-泛型new()8759
测试5-通用激活剂9166
Test6-带绑定的通用激活器60772
基线322
这是从Lasse V.Karlsen的回答中采纳的,但重要的是包括泛型。请注意,指定绑定会将使用泛型的Activator的速度降低6倍以上
using System;
using System.Reflection;
using System.Diagnostics;
namespace ConsoleApplication1
{
public class TestClass
{
}
class Program
{
static void Main(string[] args)
{
const int IterationCount = 100000000;
// warmup
Test1();
Test2();
Test3();
Test4<TestClass>();
Test5<TestClass>();
Test6<TestClass>();
// profile Activator.CreateInstance<T>()
Stopwatch sw = Stopwatch.StartNew();
for (int index = 0; index < IterationCount; index++)
Test1();
sw.Stop();
Console.WriteLine("Test1 - Activator.CreateInstance<T>(): {0}", sw.ElapsedMilliseconds);
// profile new T()
sw.Restart();
for (int index = 0; index < IterationCount; index++)
Test2();
sw.Stop();
Console.WriteLine("Test2 - new T() {0}", sw.ElapsedMilliseconds);
// profile Delegate
sw.Restart();
for (int index = 0; index < IterationCount; index++)
Test3();
sw.Stop();
Console.WriteLine("Test3 - Delegate {0}", sw.ElapsedMilliseconds);
// profile generic new()
sw.Restart();
for (int index = 0; index < IterationCount; index++)
Test4<TestClass>();
sw.Stop();
Console.WriteLine("Test4 - Generic new() {0}", sw.ElapsedMilliseconds);
// generic Activator without bindings
sw.Restart();
for (int index = 0; index < IterationCount; index++)
Test5<TestClass>();
sw.Stop();
Console.WriteLine("Test5 - Generic activator {0}", sw.ElapsedMilliseconds);
// profile Activator with bindings
sw.Restart();
for (int index = 0; index < IterationCount; index++)
Test6<TestClass>();
sw.Stop();
Console.WriteLine("Test6 - Generic activator with bindings {0}", sw.ElapsedMilliseconds);
// profile Baseline
sw.Restart();
for (int index = 0; index < IterationCount; index++)
TestBaseline();
sw.Stop();
Console.WriteLine("Baseline {0}", sw.ElapsedMilliseconds);
}
public static void Test1()
{
var obj = Activator.CreateInstance<TestClass>();
GC.KeepAlive(obj);
}
public static void Test2()
{
var obj = new TestClass();
GC.KeepAlive(obj);
}
static Func<TestClass> Create = delegate
{
return new TestClass();
};
public static void Test3()
{
var obj = Create();
GC.KeepAlive(obj);
}
public static void Test4<T>() where T : new()
{
var obj = new T();
GC.KeepAlive(obj);
}
public static void Test5<T>()
{
var obj = ((T)Activator.CreateInstance(typeof(T)));
GC.KeepAlive(obj);
}
private const BindingFlags anyAccess = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
public static void Test6<T>()
{
var obj = ((T)Activator.CreateInstance(typeof(T), anyAccess, null, null, null));
GC.KeepAlive(obj);
}
static TestClass x = new TestClass();
public static void TestBaseline()
{
GC.KeepAlive(x);
}
}
}
使用系统;
运用系统反思;
使用系统诊断;
命名空间控制台应用程序1
{
公共类TestClass
{
}
班级计划
{
静态void Main(字符串[]参数)
{
常量int迭代计数=100000000;
//热身
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
//profile Activator.CreateInstance()
秒表sw=Stopwatch.StartNew();
for(int index=0;index(MyClass)Activator.CreateInstance(typeof(MyClass));
new MyClass();
Test1 - Activator.CreateInstance<T>(): 8542
Test2 - new T() 1082
Test3 - Delegate 1214
Test4 - Generic new() 8759
Test5 - Generic activator 9166
Test6 - Generic activator with bindings 60772
Baseline 322
using System;
using System.Reflection;
using System.Diagnostics;
namespace ConsoleApplication1
{
public class TestClass
{
}
class Program
{
static void Main(string[] args)
{
const int IterationCount = 100000000;
// warmup
Test1();
Test2();
Test3();
Test4<TestClass>();
Test5<TestClass>();
Test6<TestClass>();
// profile Activator.CreateInstance<T>()
Stopwatch sw = Stopwatch.StartNew();
for (int index = 0; index < IterationCount; index++)
Test1();
sw.Stop();
Console.WriteLine("Test1 - Activator.CreateInstance<T>(): {0}", sw.ElapsedMilliseconds);
// profile new T()
sw.Restart();
for (int index = 0; index < IterationCount; index++)
Test2();
sw.Stop();
Console.WriteLine("Test2 - new T() {0}", sw.ElapsedMilliseconds);
// profile Delegate
sw.Restart();
for (int index = 0; index < IterationCount; index++)
Test3();
sw.Stop();
Console.WriteLine("Test3 - Delegate {0}", sw.ElapsedMilliseconds);
// profile generic new()
sw.Restart();
for (int index = 0; index < IterationCount; index++)
Test4<TestClass>();
sw.Stop();
Console.WriteLine("Test4 - Generic new() {0}", sw.ElapsedMilliseconds);
// generic Activator without bindings
sw.Restart();
for (int index = 0; index < IterationCount; index++)
Test5<TestClass>();
sw.Stop();
Console.WriteLine("Test5 - Generic activator {0}", sw.ElapsedMilliseconds);
// profile Activator with bindings
sw.Restart();
for (int index = 0; index < IterationCount; index++)
Test6<TestClass>();
sw.Stop();
Console.WriteLine("Test6 - Generic activator with bindings {0}", sw.ElapsedMilliseconds);
// profile Baseline
sw.Restart();
for (int index = 0; index < IterationCount; index++)
TestBaseline();
sw.Stop();
Console.WriteLine("Baseline {0}", sw.ElapsedMilliseconds);
}
public static void Test1()
{
var obj = Activator.CreateInstance<TestClass>();
GC.KeepAlive(obj);
}
public static void Test2()
{
var obj = new TestClass();
GC.KeepAlive(obj);
}
static Func<TestClass> Create = delegate
{
return new TestClass();
};
public static void Test3()
{
var obj = Create();
GC.KeepAlive(obj);
}
public static void Test4<T>() where T : new()
{
var obj = new T();
GC.KeepAlive(obj);
}
public static void Test5<T>()
{
var obj = ((T)Activator.CreateInstance(typeof(T)));
GC.KeepAlive(obj);
}
private const BindingFlags anyAccess = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
public static void Test6<T>()
{
var obj = ((T)Activator.CreateInstance(typeof(T), anyAccess, null, null, null));
GC.KeepAlive(obj);
}
static TestClass x = new TestClass();
public static void TestBaseline()
{
GC.KeepAlive(x);
}
}
}
//Too bad!!!
T someResult = (T)Activator.CreateInstance(
typeof(T),
//parameter
new object[] {id}
);