空指针测试性能

测试C#中的引用类型变量是否为空指针(如if (x == null) …)与测试小于零的整数或甚至bool为false相比,性能如何?

关于此类空指针测试是否还有其他问题,例如是否生成了garbadge

我为游戏的每一帧做了数百次这些测试,我想知道这些是否会导致问题或者能否更有效地实施?

无效测试可能等同于简单的“等于0”测试。 它们非常非常便宜 – 除非你有数百万的帧速率,否则每帧数百只应该是完全无关紧要的:)

您应该对您的应用进行分析,以找出实际花费的时间 – 这比仅仅猜测更有效率。 理想情况下,您还应尝试编写一些基准测试,以便您不仅可以测量当前性能,还可以注意由于任何特定更改而导致其显着恶化。

测试null的值不是一个复杂的操作,需要进行类型检查或类似的操作,并且不涉及内存分配。

if (x == null)给出反汇编语句:

 00000030 cmp qword ptr [rsp+20h],0 00000036 jne 000000000000004A 

即测试是作为指针值的简单整数比较实现的。

像您一样进行密集检查可能会导致性能下降,但这只能通过您自己的特定应用程序标准来衡量。

根据测试的重点,您可以通过其他方式更智能地了解检查的内容和时间。 但是,如果不了解您的应用程序的更多信息,那么尝试回答这个问题就太难了。

可能是主观的 – 但是空检查相当于一个等于零的检查,同样快。 所以我认为你不应该担心这一点。

同样 – 除非你有性能问题,否则为什么还要玩它。

同样,如果遇到性能问题,最有可能的是,您将能够从复杂的代码分支中获取性能,而不是消除一些空检查。

也就是说,对于条件代码,潜在的性能提升(但是它将严重需要进行基准测试)可能是使用委托来处理由于一个或多个条件变化而设置的不同逻辑分支 – 但我会如果这样的解决方案在一般情况下实际上提高了性能,那就会感到惊讶 – 特别是对于”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]很复杂时,这种事情会获得最大的改进,并且至关重要的是,已经certificate通过分析可以占用大量的处理器时间 。 使用委托也会对条件分支带来轻微的开销,但如果该开销少于[condition]的执行,那么它可以产生影响,特别是如果这些检查是非常频繁地执行的话。

还有其他变体,最常见的是从值派生的函数查找表,而不是基于等式检查选择代码分支(这是可以实现的大型switch / case语句 – 委托添加到由字符串键入的Dictionary正在检查枚举/值 – 这避免了多次检查值。

但最终,如果没有尽职调查(当然是前后),进行这样的优化从根本上说是没有意义的。

if (x == null)没有问题(性能或其他if (x == null)

这绝对不是问题 – 你提到的所有测试通常需要一个时钟周期。 如果条件分支对性能产生影响,则通常由不可预测或至少难以预测的分支行为导致分支预测器结束并且需要对推测执行的分支进行中止。