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

时间:2015-12-02 07:49:11

标签: performance actionscript-3 flash

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

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

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

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

-OR -

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

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

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

我对这里的表现过于戏剧化吗?

提前致谢

的Eyal

2 个答案:

答案 0 :(得分:3)

很可能解析名称的时间比实际比较要长得多。但这在很大程度上取决于您的代码结构,范围的嵌套以及编译器使用它的优化。 我怀疑这个问题在整体表现上真的很重要。我猜你在这里进行微观优化。

无论如何,你可以做些什么来评估问题,看一下生成的字节码。剥离不相关部分的代码,保留范围的结构并反编译结果。

即。假设您将此代码放在空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);

答案 1 :(得分:0)

这不是一个相关的问题,因为你的第二个案例是第一个案例+任务。因此的第二种情况根本不可能更快。

为什么还限制为2个选项?直接评估实例也非常有效:

if(myDecorator)
{ etc ....