c# - Object.GetType() 的性能

标签 c# .net performance

我们的应用程序中有很多记录调用。我们的记录器采用 System.Type 参数,因此它可以显示哪个组件创建了调用。有时,当我们被打扰时,我们会做这样的事情:

class Foo
{
  private static readonly Type myType = typeof(Foo);

  void SomeMethod()
  {
     Logger.Log(myType, "SomeMethod started...");
  }
 }

因为这只需要获取 Type 对象一次。但是,我们对此没有任何实际指标。有谁知道每次登录时调用 this.GetType() 可以节省多少?

(我意识到我可以自己完成指标,没有大问题,但是嘿,StackOverflow 有什么用?)

最佳答案

我强烈怀疑 GetType() 将花费比任何实际日志记录少得多的时间。当然,您对 Logger.Log 的调用有可能不会执行任何实际的 IO...不过我仍然怀疑这种差异是无关紧要的。

编辑:基准代码在底部。结果:

typeof(Test): 2756ms
TestType (field): 1175ms
test.GetType(): 3734ms

这就是调用该方法 100 百万 次 - 优化获得了几秒钟左右的时间。我怀疑真正的日志记录方法将有更多工作要做,并且调用 1 亿次将花费比 4 秒更长的总时间,即使它没有写出任何东西。 (当然,我可能是错的——你必须自己尝试。)

换句话说,像往常一样,我会选择最易读的代码,而不是进行微优化。

using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;

class Test
{
    const int Iterations = 100000000;

    private static readonly Type TestType = typeof(Test);

    static void Main()
    {
        int total = 0;
        // Make sure it's JIT-compiled
        Log(typeof(Test)); 

        Stopwatch sw = Stopwatch.StartNew();
        for (int i = 0; i < Iterations; i++)
        {
            total += Log(typeof(Test));
        }
        sw.Stop();
        Console.WriteLine("typeof(Test): {0}ms", sw.ElapsedMilliseconds);

        sw = Stopwatch.StartNew();
        for (int i = 0; i < Iterations; i++)
        {
            total += Log(TestType);
        }
        sw.Stop();
        Console.WriteLine("TestType (field): {0}ms", sw.ElapsedMilliseconds);

        Test test = new Test();
        sw = Stopwatch.StartNew();
        for (int i = 0; i < Iterations; i++)
        {
            total += Log(test.GetType());
        }
        sw.Stop();
        Console.WriteLine("test.GetType(): {0}ms", sw.ElapsedMilliseconds);
    }

    // I suspect your real Log method won't be inlined,
    // so let's mimic that here
    [MethodImpl(MethodImplOptions.NoInlining)]
    static int Log(Type type)
    {
        return 1;
    }
}

关于c# - Object.GetType() 的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/353342/

相关文章:

c# - 为什么我没有收到 "Cross-thread operation not valid"错误

c# - 如何将其建模为 LINQ 查询?

java - 通过调用 DAO.getAll() 避免收集大量 ID

javascript - onkeyup 事件触发延迟

c# - OnResize 与 OnSizeChanged

c# - WPF 中的 OuterGlow 效果不适用于分层窗口?

c# - 如何从 C# 中的 pvk 文件中读取私钥?

java - Grails 与 REST 的 Spring 性能

javascript - 至少一个字符和一个数字且重复不超过两个的正则表达式

c# - 使用c#在代码后面动态添加CSS类