2015-12-02 45 views
1

假设我有一个函数叫做drawGraphics,它在某些预定义的配置下运行非常紧3秒。AS3> performance> if(myBooleanField)* VS * if(myObjectField!= null)* VS * if(myIntField!= 0)

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

我可以使用两个选项来运行这段代码:

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

- 或 -

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

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

哪个更有效:比较字段为空或询问是否一个布尔字段为“真” (或比较一个int字段为0)?

我是否过度戏剧化表演?

在此先感谢

的Eyal

+0

这不是一个相关的问题,因为你的第二种情况是第一种情况+任务。出于这个原因的第二种情况根本不可能更快。 – BotMaster

+0

区别在于微乎其微。即使在3秒的持续时间内,我怀疑你会看到'isUsingDecorator'提高了1ms,瓶颈肯定是在其他地方。但你确实需要做一些测量才能知道。 – Aaron

回答

3

最有可能名称解析花费的时间比实际比较远长。但这很大程度上取决于您的代码结构,作用域的嵌套以及编译器使用它的优化。 我怀疑这个问题在整体表现中确实很重要。我猜你在这里是微型优化。

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

I.e.假设你有这样的代码在一个空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  

现在我们可以看到将测试与空比较需要三条指令:getlex,pushnull,ifeq;并检查一个布尔值产生两条指令:getlex,iffalse。在这方面唯一值得关注的就是用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); 
+0

谢谢诺克斯诺克斯,很好的回答! ...并用字节码测试这个问题是一个很好的方式来回答它... –

+0

@EyalKatz为什么不接受它。 :) –

+0

的确如此。完成。 :) –

0

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

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

if(myDecorator) 
{ etc ....