空指针测试性能

本文关键字:性能 测试 空指针 | 更新日期: 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)没有任何问题

这绝对不是问题——您提到的所有测试通常只需要一个时钟周期。如果条件分支对性能有影响,通常是由于不可预测或至少难以预测的分支行为干扰了分支预测器,并要求终止推测执行的分支。