【问题标题】:Which is more efficient: myType.GetType() or typeof(MyType)?哪个更有效:myType.GetType() 或 typeof(MyType)?
【发布时间】:2013-05-24 17:32:57
【问题描述】:

假设我有一个班级MyType

sealed class MyType
{
    static Type typeReference = typeof(MyType);
    //...
}

给定以下代码:

var instance = new MyType();
var type1 = instance.GetType();
var type2 = typeof(MyType);
var type3 = typeReference;

这些变量分配中哪一个最有效?

GetType() 或 typeof() 的性能是否足够考虑到将类型保存在静态字段中?

【问题讨论】:

  • 您是在运行时获取实例(动态、泛型?)还是在编译时指定?
  • @newStackExchangeInstance 我只是在我提供的确切代码的上下文中询问。

标签: c# .net runtime-type


【解决方案1】:

typeof(SomeType) 是一个简单的元数据令牌查找

GetType() 是虚拟通话;从好的方面来说,如果它是子类,您将获得派生类型,但在不利方面,如果它是子类,您将获得派生类。如果你明白我的意思。此外,GetType() 需要对结构进行装箱,并且不适用于可为空的结构。

如果您在编译时知道类型,请使用typeof()

【讨论】:

  • GetType 如何要求对结构进行装箱?
  • @Dan 因为它是一个不能被覆盖的虚拟调用。所有其他结构方法(Equals、ToString、GetHashCode 等)都可以被覆盖,这允许通过调用或约束调用在不装箱的情况下调用它们。但是在结构上调用非覆盖方法需要装箱,然后在对象上调用虚方法。
  • 知道了。我从来没有想过。谢谢!
  • @Dan 然而,一个有趣的观察是,在所有涉及结构的非泛型情况下,编译器实际上可以(但它不会)用 typeof 替换 GetType()。尽管 nullable-T 情况下的“正确”行为值得怀疑。
【解决方案2】:

我会选择 type2。它不需要实例化实例来获取类型。而且它是人类可读性最强的。

【讨论】:

  • 这些都很好,但我更关心效率而不是可读性。
【解决方案3】:

找出答案的唯一方法是测量。

“type1”变体在任何情况下都不可靠或不推荐,因为并非所有类型都可以构造。更糟糕的是,它分配的内存需要作为垃圾收集器并调用对象构造函数。

对于剩下的两个选项,在我的机器上,“type3”在调试和发布模式下的速度大约是“type1”的两倍。请记住,这仅适用于我的测试 - 结果可能不适用于其他处理器类型、机器类型、编译器或 .NET 版本。

        var sw = System.Diagnostics.Stopwatch.StartNew();
        for (int i = 0; i < 10000000; i++)
        {
            var y = typeof(Program).ToString();
        }
        sw.Stop();
        Console.WriteLine(sw.ElapsedMilliseconds);

        sw.Restart();
        for (int i = 0; i < 10000000; i++)
        {
            var y = typeReference.ToString();
        }
        sw.Stop();
        Console.WriteLine(sw.ElapsedMilliseconds);

也就是说,在没有明确要求的情况下提出这个问题有点令人担忧。如果您注意到性能问题,您可能已经对其进行了分析并知道哪个选项更好。这告诉我这很可能是过早的优化 - 你知道“过早的优化是万恶之源”的说法。

编程代码不仅仅通过性能来衡量。它还通过正确性、开发人员生产力和可维护性来衡量。在没有strong理由的情况下增加代码的复杂性只会将成本转移到其他地方。对于现在和未来的应用程序维护者来说,本来可能不是问题的事情现在变成了生产力的严重损失。

我的建议是始终使用“type1”变体。我列出的测量代码不是真实世界的场景。将 typeof 缓存到引用变量可能会产生大量副作用,尤其是在 .NET 加载程序集的方式方面。与其只在需要时加载它们,不如在每次使用应用程序时都加载它们——将理论上的性能优化变成一个非常实际的性能问题。

【讨论】:

  • 抱歉,如果回复有点说教,我只是在想象谷歌会接受这个,成千上万的初学者开发人员突然抛弃了 typeof() 运算符!
【解决方案4】:

它们完全不同。

typeof(MyType) 获取一个 Type 对象,该对象描述了使用 ldtoken 指令在编译类型中解析的 MyType 类型。

myInstance.GetType() 获取描述myInstance 变量的运行时类型的Type 对象。

两者都适用于不同的场景。

您不能使用typeof(MyType),除非您在编译时知道类型并且可以访问它。

您不能使用myInstance.GetType(),除非您有该类型的实例。

typeof(MyType) 总是更高效,但如果在编译时看不到类型,则无法使用。您不能使用typeof(MyType) 了解某个变量的真实运行时类型,因为您不知道类型。

【讨论】:

  • 我理解它们在使用方面的差异。对于我发布的示例,结果将是相同类型的对象。我的问题是哪个更有效,为什么?
【解决方案5】:

两者基本相同。虽然 typeof 可以用于像

这样的非实例类
typeof(MyClass);

但是

MyClass.GetType();

甚至不会构建,因为您需要拥有该类的实例。

长话短说,他们都在不同的环境中做同样的工作。

【讨论】:

  • 我知道我提供的所有 3 个变量赋值在功能上都是等效的,但我想知道哪个更有效。
  • 从技术上讲 typeof 会更快。
  • 我只讲技术。我不知道怎么不。是什么让您说它更高效?
  • 我已经修改了我的立场。由于 typeof(Class) 返回一个 System.Type 对象,两种语法形式将使用相同的机制。如前所述,唯一的区别是 typeof 只能用于非实例化类,而 Object.GetType() 要求对象是实例化的。
  • “非实例类”是什么意思?
猜你喜欢
  • 2010-12-22
  • 1970-01-01
  • 1970-01-01
  • 2014-03-03
  • 2012-08-25
  • 1970-01-01
  • 2010-10-22
  • 2019-04-25
  • 2012-03-12
相关资源
最近更新 更多