空指针测试性能
本文关键字:性能 测试 空指针 | 更新日期: 2023-09-27 17:52:44
测试c#中的引用类型变量是否为空指针(如if (x == null)
…)与测试整数小于零甚至bool为false相比,性能如何?
我为游戏的每一帧做了数百次这样的测试,我想知道这些是否会导致问题,或者是否可以更有效地执行?
null测试可能等同于简单的"等于0"测试。它们非常,非常便宜-除非你有数百万的帧率,否则每帧几百应该是完全微不足道的:)
你应该分析你的应用程序,找出实际上花在哪里了——这比仅仅猜测要有效率得多。理想情况下,您还应该尝试编写一些基准测试,这样您不仅可以测量当前的性能,而且还可以注意到由于任何特定更改而导致性能明显变差。
测试null值不是一个复杂的操作,不需要类型检查或类似的东西,也不涉及内存分配。
反汇编语句if (x == null)
给出:
00000030 cmp qword ptr [rsp+20h],0
00000036 jne 000000000000004A
。该测试实现为指针值的简单整数比较。
像这样做密集的检查可能会有一些性能下降,但是,这只能通过你自己的标准来衡量。
基于测试的重点,可能有其他方法可以让你更聪明地选择&当你检查的时候。但是,如果不了解您的应用程序的更多信息,就很难想出这个问题的答案。
可能是主观的-但是null检查等同于等于零检查,并且同样快速。所以我认为你不应该担心这个。
同样-除非你有性能问题,否则为什么要玩它。
同样,如果您确实有性能问题,那么您很可能能够从复杂的代码分支中获得性能,而不是消除一些null检查。
也就是说,对于条件代码,一个潜在的性能改进(然而它需要认真地进行基准测试)可能是为不同的逻辑分支使用委托,这些分支是作为一个或多个条件更改的结果而设置的——但是如果这样的解决方案实际上在一般情况下提高了性能,我会感到惊讶——特别是对于您的'is null'场景。我的意思是像这样:
if([condition])
{
Foo();
}
else
{
Bar();
}
如果,说,[condition]
涉及到一个局部变量_obj
(在你的例子中是_obj == null
) -你可以用这样的东西替换(但要非常非常小心线程问题):
private Action _logic;
private object _obj;
public Object Obj {
get { return Obj; }
set {
_obj=value;
if([condition])
_logic = () => Foo();
else
_logic = () => Bar();
}
}
现在在任何代码中,你之前已经检查了[condition]
进行分支,你现在只需执行:
_logic();
当[condition]
很复杂时,这种事情获得了最大的改进,关键的是,通过分析被证明占用了大量的处理器时间。使用委托也会在条件分支上带来一点开销,但是如果这个开销小于[condition]
的执行,那么它就会有所不同,特别是当这些检查非常频繁地执行时。
这也有其他的变化,最常见的函数查找表是从一个值派生出来的,而不是根据相等性检查选择一个代码分支(这就是可以实现大型switch/case语句的方式——通过被检查的enum/value键添加到Dictionary
的委托——这避免了对值的多次检查)。
最终,虽然,没有尽职调查的分析(之前和之后,当然),执行这样的优化基本上是毫无意义的。
if (x == null)
没有任何问题
这绝对不是问题——您提到的所有测试通常只需要一个时钟周期。如果条件分支对性能有影响,通常是由于不可预测或至少难以预测的分支行为干扰了分支预测器,并要求终止推测执行的分支。