我看到类似于以下代码的一些原生WPF控件:
static MyControl {
Type typeFromHandle = typeof(MyControl);
// Which is used in various places
SomeProperty.OverrideMetadata(typeFromHandle, ...);
CommandManager.RegisterClassInputBinding(typeFromHandle, ...);
EventManager.RegisterClassHandler(typeFromHandle, ...);
}
似乎以下代码具有相同的性能:
static MyControl {
SomeProperty.OverrideMetadata(typeof(MyControl), ...);
CommandManager.RegisterClassInputBinding(typeof(MyControl), ...);
EventManager.RegisterClassHandler(typeof(MyControl), ...);
}
在JIT代码或运行时期间,这种方法是否提供了任何性能优势?
答案 0 :(得分:18)
typeof
的缓存将为您带来小的性能提升。 following page gives基准:
Typeof expression used: 2.55 ns
Type object cached: 0.64 ns
如果你typeof
很多,或者关心纳秒,那么这对你来说可能很重要!
答案 1 :(得分:13)
简短回答
是的,它更优,但不,你不应该使用它,因为几乎每个情况下它是一个不成熟的优化。如果您使用typeof(MyControl)
多次,请将其用作保持代码可读性的方法。
答案很长
如果你看一下C#中typeof(MyControl)
语句产生的IL,你会看到以下内容:
IL_0001: ldtoken [mscorlib]MyControl
IL_0006: call class [mscorlib]System.Type
[mscorlib]System.Type::GetTypeFromHandle(
valuetype [mscorlib]System.RuntimeTypeHandle)
这些说明执行以下操作:
RuntimeTypeHandle
(ldtoken
IL指令)加载到堆栈中(CLR一,而不是C#/。NET概念)。Type
(致电Type.GetTypeFromHandle
)获取RuntimeTypeHandle
。将此与指定Type变量类型与存储在实例中的类型进行比较:
IL_0014: ldloc.2
注意,位置(1,2等)将根据其他变量而变化,但最终,它是参考类型的负载。
比较两者,对已经分配的变量的调用总是会更快。第一个必须加载类型句柄,然后必须调用方法才能将句柄解析为Type
;第二种方法只是对局部变量的引用。
然而,像大多数其他帖子一样,这绝对可以被视为过早优化的情况,因此如果您认为您的代码表现不佳,我建议不要这样做。
从代码重用的角度来看,可以做出更好的论证,就像你必须改变类型一样,你可以在更少的地方改变它;你不会充斥着typeof
陈述的海洋。
最后,关于WPF,考虑到性能要求(就像任何UI系统一样),这是他们必须要做的事情; WPF拥有大量的托管对象,与Windows窗体相比还要多得多,并且必须考虑这些对象的性能,以便尽可能快地呈现UI。
结果,你会看到这样的东西:
private static readonly object TrueObject = true;
private static readonly object FalseObject = false;
// Later on.
DoSomething(condition ? TrueObject : FalseObject);
// Where
void DoSomething(object value)
{
// Compare to true/false objects.
if (value == TrueObject)
{
// True case.
}
else if (value == FalseObject)
{
// False case.
}
else
{
// Invalid.
throw new InvalidOperationException();
}
}
原因很简单;大多数WPF使用对象作为参数而不是强类型值公开属性/方法。当涉及到值类型时,它可能涉及大量的装箱/拆箱。
为了解决这个问题,他们有一个单实例,当他们知道确切地将哪些值打包/取消装箱时,这些实例会被装箱/取消装箱;使用bool
,很容易,只有true
和false
。
同样,对于几乎任何系统,我不一定会推荐这种方法,但对于某些系统,它是有道理的。
在您的情况下,我只是将类型分配给变量,仅用于可读性目的,而不是用于性能。如果您遇到性能问题,请先查看整个过程,通过测量进行隔离,然后从那里开始。
答案 2 :(得分:5)
你不太可能编写typeof性能显着的代码,所以你应该选择最清晰和可维护的代码风格。