2012-08-09 11 views
2

我有一個嵌套多個層次的對象,我多次引用它。創建和設置對該對象的引用是否更快?還是它很重要?在ActionScript中設置對嵌套對象的局部變量的引用是否更快?

上下文 我聽說創建本地引用的速度更快。這是幾年前的一個Visual Basic項目。但這是Flash。輸出是一個SWF /字節碼。編譯器可以查看該引用並執行我正在做的操作,以便每次都不必查看該對象。

例如:

public function doStuff():void { 

    Model.instance.view1.button1 = button1; 
    Model.instance.view1.button2 = button2; 
    Model.instance.view1.button3 = button3; 
    Model.instance.view1.button4 = button4; 
    Model.instance.view1.button5 = button5; 
    Model.instance.view1.button6 = button6; 

    // more fake code referencing more something.something.something like things 

    for (var i:int;i<something.something.something.length;i++) { 
     var result:Object = Controller.staticMethod(button1); 
     var result2:Object = Controller.staticMethod(button1); 
    } 
} 

Vs的:

public function doStuff():void { 
    var view1:View = Model.instance.view1; 

    view1.button1 = button1; 
    view1.button2 = button2; 
    view1.button3 = button3; 
    view1.button4 = button4; 
    view1.button5 = button5; 
    view1.button6 = button6; 
} 


考慮Baris的建議我自己測試了一下。下面是結果(雖然我不知道如何將它們解釋爲實際差異,即'方法1比方法2快0.000001')。

結果

測試1

  var instance:Model = Model.instance; 

      var startTime:int = getTimer(); 
      for(var i:int = 0; i<10000000; i++){ 
       instance.url = ""; 
      } 
      trace(getTimer()-startTime); // 826, 929, 823 

      var startTime:int = getTimer(); 
      for(var i:int = 0; i<10000000; i++){ 
       Model.instance.url = ""; 
      } 
      trace(getTimer()-startTime); // 3483, 3976, 3539 

測試2

  var instance:Model = Model.instance; 

      var localLogo:BitmapImage = Model.instance.logo; 

      var startTime:int = getTimer(); 
      for(var i:int = 0; i<10000000; i++){ 
       localLogo = logo; 
      } 
      trace(getTimer()-startTime); // 2070, 2083, 2110 

      var startTime:int = getTimer(); 
      for(var i:int = 0; i<10000000; i++){ 
       instance.logo = logo; 
      } 
      trace(getTimer()-startTime); // 2028, 2509, 2154 

回答

3

通常,as3編譯器不像我們想象的那麼聰明。我認爲這樣做可以縮短編譯時間。

本頁面http://upshots.org/actionscript/20-tips-to-optimize-your-actionscript爲我們提供了一個規則:

5:單點規則當訪問嵌套的變量,任何時候一個 變量需要範圍轉移來發現即使只有一個級別,並且是 引用超過一次,將其保存到局部變量。在繪製 類時,您經常會看到循環內引用的Math.PI/2,因此 可能每幀重複數百次 - 該值應該是 存儲在局部變量中。請注意,當 引用成員方法時,情況並非如此。將Math.PI保存到一個變量是 合適的;將Math.round保存到變量不是。

它確實差,但軟件建設的角度來看,更可讀的代碼將是propper辦法做到這一點,除非它的關鍵代碼,就像你的應用程序的物理部分。

除了製作時間基準,您可以檢查字節碼太多,使用此工具http://www.swfwire.com/

2

我喜歡:

public function doStuff():void { 
    var view1:View = Model.instance.view1; 

    view1.button1 = button1; 
    view1.button2 = button2; 
    view1.button3 = button3; 
    view1.button4 = button4; 
    view1.button5 = button5; 
    view1.button6 = button6; 
} 

我認爲它看起來更清潔,你可以分析並查看哪一個更快,但如果您不在內部循環中執行這麼多次,性能方面無關緊要。

public function doStuff():void { 
    var startTime:int = getTimer(); 
    for(var i:int = 0; i<1000000; i++){ 
     Model.instance.view1.button1 = button1; 
     Model.instance.view1.button2 = button2; 
     Model.instance.view1.button3 = button3; 
     Model.instance.view1.button4 = button4; 
     Model.instance.view1.button5 = button5; 
     Model.instance.view1.button6 = button6; 
    } 
    trace(getTimer()-startTime); 
} 

public function doStuff():void { 
    var startTime:int = getTimer(); 
    for(var i:int = 0; i<1000000; i++){ 
     var view1:View = Model.instance.view1; 

     view1.button1 = button1; 
     view1.button2 = button2; 
     view1.button3 = button3; 
     view1.button4 = button4; 
     view1.button5 = button5; 
     view1.button6 = button6; 
    } 
    trace(getTimer()-startTime); 
} 
+0

我使用Model.instance.button1 = button1 vs var localInstance.button1 = button1運行這些10,000,000次,差異爲 Model6.06.ms爲6206ms,localInstance.button1 = button1爲2947ms。問題在於區別,因爲實例是一個getter或是查找。去嘗試另一個測試... – 2012-08-09 18:00:40

+1

你可能永遠不會做這樣的事情,所以我不會太擔心哪一個更快,只需選擇一個對你(或你的團隊)更具可讀性的堅持下去。 – 2012-08-09 18:06:03

+0

我剛剛更新了測試結果的問題。因此,使用百萬次循環,你如何找出差異是什麼?我的意思是說,給你的結果你會說,「它快0.00001秒」? – 2012-08-09 18:22:43

2

的時間訪問可能是無關緊要的,因爲你似乎在做一些用戶界面的工作,和毫秒的分數將採取沒有關係。還有其他一些問題:

  1. 您正在編寫重複的代碼 - 這是不好的,總是。如果它必須重複必須,你應該編寫一個程序,在任何地方從單一來源重複它,如果它可能不會重複 - 選擇不重複。關注很簡單。一旦您發現按鈕位於ModelB.instance.view1中,您將需要多次複製和粘貼相同的代碼 - 當然在做重複性的工作時您會犯錯誤。

  2. AS3代碼不僅允許,它也歡迎副作用,在這種情況下,可能會產生不良影響。例如,Model.instance.view1可能是一個getter,它在每次訪問時都會返回一個新的視圖副本,或者,在訪問時,它可能會改變實例內部狀態中的其他內容,無論它是什麼,並多次執行此更改不可取的。

  3. 有德米特的規則。當儘可能簡化時,它表示您不應該多次使用單點算子。即一個對象可能只知道它自己的屬性(或局部變量)的屬性,但決不會訪問該屬性的屬性,也不會進一步下線。這對您的程序結構施加了不必要的限制。然而,有時看起來它可能很難避免,你應該爭取一個更好的,自包含的代碼。更多關於德米特的規則在這裏:http://en.wikipedia.org/wiki/Law_of_Demeter

它不是編譯器特別是由於副作用「優化」這樣的代碼,的函數。編譯器會忠實地遵循程序員編寫的錯誤代碼,併產生很多重複的程序集,因爲它信任程序員該代碼實際上是需要的。請注意,我不是在談論Adobe編譯器,它不是一個優化編譯器,即使靜態分析提示,也不會刪除此代碼。我正在談論一些針對該語言的抽象「理想」編譯器,這將最優化地編譯有問題的代碼。