2015-12-02 56 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 ....