gpt4 book ai didi

.net - System.Activator.CreateInstance(T) 是否存在足以阻止我们随意使用它的性能问题?

转载 作者:行者123 更新时间:2023-12-03 09:01:38 25 4
gpt4 key购买 nike

是否 System.Activator.CreateInstance(T)方法是否存在性能问题(因为我怀疑它使用反射)足以阻止我们随意使用它?

最佳答案

与往常一样,回答有关性能的问题的唯一正确方法是实际测量代码。

这是一个示例 LINQPad测试程序:

  • 激活器.CreateInstance
  • 新 T()
  • 调用调用 new T()
  • 的委托(delegate)

    与往常一样,对性能程序持保留态度,这里可能存在会影响结果的错误。

    输出(计时值以毫秒为单位):
    Test1 - Activator.CreateInstance<T>() 12342 Test2 - new T() 1119 Test3 - Delegate 1530 Baseline 578 

    Note that the above timings are for 100.000.000 (100 million) constructions of the object. The overhead might not be a real problem for your program.

    Cautionary conclusion would be that Activator.CreateInstance<T> is taking roughly 11 times as much time to do the same job as a new T() does, and a delegate takes roughly 1.5 times as much. Note that the constructor here does nothing, so I only tried to measure the overhead of the different methods.

    Edit: I added a baseline call that does not construct the object, but does the rest of the things, and timed that as well. With that as a baseline, it looks like a delegate takes 75% more time than a simple new(), and the Activator.CreateInstance takes around 1100% more.

    However, this is micro-optimization. If you really need to do this, and eek out the last ounce of performance of some time-critical code, I would either hand-code a delegate to use instead, or if that is not possible, ie. you need to provide the type at runtime, I would use Reflection.Emit to produce that delegate dynamically.

    In any case, and here is my real answer:

    If you have a performance problem, first measure to see where your bottleneck is. Yes, the above timings might indicate that Activator.CreateInstance has more overhead than a dynamically built delegate, but there might be much bigger fish to fry in your codebase before you get (or even have to get) to this level of optimization.

    And just to make sure I actually answer your concrete question: No, I would not discourage use of Activator.CreateInstance. You should be aware that it uses reflection so that you know that if this tops your profiling lists of bottlenecks, then you might be able to do something about it, but the fact that it uses reflection does not mean it is the bottleneck.

    The program:

    void Main()
    {
    const int IterationCount = 100000000;

    // warmup
    Test1();
    Test2();
    Test3();
    Test4();

    // profile Activator.CreateInstance<T>()
    Stopwatch sw = Stopwatch.StartNew();
    for (int index = 0; index < IterationCount; index++)
    Test1();
    sw.Stop();
    sw.ElapsedMilliseconds.Dump("Test1 - Activator.CreateInstance<T>()");

    // profile new T()
    sw.Restart();
    for (int index = 0; index < IterationCount; index++)
    Test2();
    sw.Stop();
    sw.ElapsedMilliseconds.Dump("Test2 - new T()");

    // profile Delegate
    sw.Restart();
    for (int index = 0; index < IterationCount; index++)
    Test3();
    sw.Stop();
    sw.ElapsedMilliseconds.Dump("Test3 - Delegate");

    // profile Baseline
    sw.Restart();
    for (int index = 0; index < IterationCount; index++)
    Test4();
    sw.Stop();
    sw.ElapsedMilliseconds.Dump("Baseline");
    }

    public void Test1()
    {
    var obj = Activator.CreateInstance<TestClass>();
    GC.KeepAlive(obj);
    }

    public void Test2()
    {
    var obj = new TestClass();
    GC.KeepAlive(obj);
    }

    static Func<TestClass> Create = delegate
    {
    return new TestClass();
    };

    public void Test3()
    {
    var obj = Create();
    GC.KeepAlive(obj);
    }

    TestClass x = new TestClass();
    public void Test4()
    {
    GC.KeepAlive(x);
    }

    public class TestClass
    {
    }

    关于.net - System.Activator.CreateInstance(T) 是否存在足以阻止我们随意使用它的性能问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6069661/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com