测试C#中的引用类型变量是否为空指针(如if (x == null)
...)与测试小于零的整数相比,性能如何?甚至布尔都是假的?
是否还有其他问题需要了解此类空指针测试,例如是 garbadge制作?
我为游戏的每一帧做了数百次这些测试,我想知道这些测试是否会导致问题或者是否可以更有效地实施?
答案 0 :(得分:12)
无效测试可能等同于简单的“等于0”测试。他们非常,非常便宜 - 除非你有数百万的帧率,否则每帧数百只应该是完全无关紧要的。)
您应该对自己的应用进行分析,以了解实际花费的时间 - 这比猜测更有效率。理想情况下,您还应该尝试编写一些基准测试,这样您不仅可以测量当前的性能,还可以注意由于任何特定的更改而导致性能显着下降。
答案 1 :(得分:3)
测试null的值不是一个复杂的操作,需要进行类型检查或类似的操作,并且不涉及内存分配。
反汇编语句if (x == null)
给出:
00000030 cmp qword ptr [rsp+20h],0
00000036 jne 000000000000004A
即。测试实现为指针值的简单整数比较。
答案 2 :(得分:2)
执行像 这样的强化检查会导致性能下降,但这只能通过您自己的标准针对您的特定应用进行衡量。
根据测试的重点,可能还有其他方法可以更明智地了解什么&当你检查。但是,在不了解您的应用程序的情况下,尝试回答这个问题会非常困难。
答案 3 :(得分:2)
可能是主观的 - 但是空检查相当于一个等于零的检查,同样快。所以我认为你不应该担心这一点。
同样 - 除非你遇到性能问题,否则为什么还要玩呢。
同样,如果您遇到性能问题,最有可能的是,您将能够从复杂的代码分支中获取性能,而不是消除一些空检查。
那就是说,对于条件代码,潜在的性能提升(但是它将严重需要进行基准测试)可能是使用委托来处理由于一个或多个条件变化而设置的不同逻辑分支 - 但是我如果这样的解决方案在一般情况下实际上提高了性能,那就会感到惊讶 - 特别是对于你的'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语句 - 委托添加到{ {1}}由被检查的枚举/值键入 - 这可以避免多次检查值。)
但最终,如果没有尽职尽责的分析(当然,之前和之后),进行这样的优化从根本上说是没有意义的。
答案 4 :(得分:1)
if (x == null)
没有问题(表现或其他方面)。
答案 5 :(得分:1)
这绝对不是问题 - 你提到的所有测试通常需要一个时钟周期。如果条件分支对性能产生影响,则通常由不可预测或至少难以预测的分支行为造成分支预测器污染并需要对推测执行的分支进行中止。