AS3 > 性能 > if (myBooleanField) *VS* if (myObjectField != null) *VS* if (myIntField != 0)

AS3 > performance > if (myBooleanField) *VS* if (myObjectField != null) *VS* if (myIntField != 0)

假设我有一个名为 drawGraphics 的函数,它 运行 在某些预定义的配置下非常紧张 3 秒。

在该函数中我可以调用 myDecorator.decorate(),前提是该字段不为空。

我可以 运行 此代码使用两个选项:

if (myDecorator != null)
    myDecorator.decorate();

-或-

// during init:
isUsingDecorator = myDecorator != null; // boolean field

// ...
// during 'drawGraphics'
if (isUsingDecorator) 
    myDecorator.decorate();

哪个更有效:将字段与 null 进行比较或询问布尔字段是否为 'true'(或将 int 字段与 0 进行比较)?

我是不是对这里的表现过于夸张了?

提前致谢

埃亚尔

很可能 解析名称比实际比较花费的时间要长得多。但这在很大程度上取决于您的代码结构、作用域的嵌套以及编译器对其进行的优化。 我怀疑这个问题对整体性能是否真的很重要。我猜你在这里进行了微优化。

无论如何,您可以通过查看生成的字节码来评估问题。去除不相关部分的代码,保留作用域的结构并反编译结果。

即假设您在空 bytecode.swf 电影的单帧中有此代码:

var test:Function = function(){};
var check:Boolean = test != null;

var action:Function = function()
{
    if (test != null) {
        trace(1);
    }
    if (check) {
        trace(2);
    }   
};

action();

使用flex_sdk_4.6\bin\swfdump.exe:

swfdump.exe -abc -showbytecode bytecode.swf > bytecode.txt

检查 bytecode.txt 并找到以下内容:

02 02 01 0B 0B 1C    var null::no name():
maxStack:2 localCount:1 initScopeDepth:11 maxScopeDepth:11
60 03                    getlex         :test
20                       pushnull       
13 07 00 00              ifeq           L0

5D 09                    findpropstrict :trace
24 01                    pushbyte       1
4F 09 01                 callpropvoid   :trace (1)
60 05                L0: getlex         :check
12 07 00 00              iffalse        L1

5D 09                    findpropstrict :trace
24 02                    pushbyte       2
4F 09 01                 callpropvoid   :trace (1)
47                   L1: returnvoid    

现在我们可以看到比较test和null需要三个指令:getlexpushnullifeq;并在两条指令中检查布尔结果:getlexiffalse。在性能方面唯一重要的是使用 getlex.

解析标识符

因此,要回答您的问题,您需要弄清楚在您的特定上下文中解决 myDecorator 问题真正需要多长时间。例如,如果 isUsingDecorator 是方法变量的局部变量而 myDecorator 不是,那么使用前者肯定会获得更好的性能。再一次,我怀疑这才是真正重要的。

P.S。您也可以使用下面的原始测试,但当性能差异如此之小或根本不存在时,它就非常不准确。不管怎样,它至少可以给你一个提示:这不是需要优化的地方。

import flash.utils.setInterval;

var test:Function = function(){};
var check:Boolean = test != null;

var action:Function = function()
{
    var a:Date;
    var s:int, i:int;

    s = getTimer();
    for(i = 0;i<100000;i++) {
        if (test != null) {
            a = new Date(); // just chewing the fat     
        }
    }
    trace("a:"+(getTimer()-s));

    s = getTimer();
    for(i = 0;i<100000;i++) {
        if (check) {
            a = new Date(); // just chewing the fat     
        }
    }   
    trace("b:"+(getTimer()-s));
};

setInterval(action, 1000);

这几乎不是一个相关的问题,因为你的第二个案例是第一个案例 + 作业。出于这个原因,第二种情况简直不能再快了。

为什么还要限制为 2 个选项?直接评估实例也是完全有效的:

if(myDecorator)
{ etc ....