2013-05-28 44 views
0

我發現自己編程的功能比迭代更多,而且經常編寫重複計算的函數。例如,不錯的編程習慣 - 哪個更高效?

function DoThis(a) 
    if something(a) - another(a) - yetanother(a) > 0 then 
     return something(a) - another(a) - yetanother(a) 
    else 
     return 0 
    end 
end 

我這樣做了很多,如果結果不會被使用超過幾次。一般來說,將計算分配給變量是否更高效?

function DoThis(a) 
    local x = something(a) - another(a) - yetanother(a) 
    if x > 0 then 
     return x 
    else 
     return 0 
    end 
end 

我明白在這種情況下,差異可能是微不足道的,但我感興趣的開發從一開始良好的生活習慣,並作爲東西堆積和複雜化,差異可能是相當大的。

+1

「我明白在這種情況下的差異可能可以忽略不計,」那麼,這取決於。 a)編譯器/解釋器是否可能只計算一次? [只有在知道沒有副作用的情況下才是合法的] b)被調用函數的代價如何?如果被調用的函數沒有副作用[並且結果很小,如果語言使用延遲評估],則始終保持安全並將結果分配給本地,以便只需計算一次。 –

+0

我不確定lua在這個頻譜上的位置。但我喜歡這種安全的聲音! – ridthyself

+2

我寧願'return math.max(0,something(a) - another(a) - yetanother(a))''沒有額外的變量。 –

回答

2

如果您不止一次需要計算結果(函數的返回值),將它存儲在變量中而不是重新計算它幾乎總是一個好主意。特別是如果功能非常複雜,因此需要很長時間來計算回憶,以便提高性能。

+0

如果我需要多次使用這個結果,以後再存儲它,這是有道理的。我想我的問題與硬件有關,如果計算機讀寫內存比物理計算更重。我想你是對的,這取決於計算。對於何時使用一種而不是另一種,是否有一個公認的規則?如果這個函數在主循環中,它可以連續運行,並且應該儘可能高效。 – ridthyself

+0

我認爲一般的規則是儘可能避免重新計算。即使您認爲讀取/寫入比計算本身需要更多時間,這應該會更快: 如果將某些內容分配給本地變量,則會在堆棧上創建此變量。如果你從一個函數中返回一個值,這個值將被調用者從被調用函數中彈出。 正如你在兩種情況下看到的,數據被寫入(同一種)內存。 – QI3it

+0

所以充其量,你有點平衡。這真的很好知道,謝謝你的洞察力。 – ridthyself

2

一旦你開始變得堅強起來,這個問題會變得非常有趣。在某些情況下,您提供的每個代碼示例都可能比其他代碼示例更高效。在的情況下

something(a) - another(a) - yetanother(a) 

總是小於或等於零,因爲你避免賦值給一個變量的第一個代碼樣品會稍微更有效,所以數從未離開用於計算的寄存器。

但是,如果該語句大於零,則第二個代碼示例的效率會高得多,因爲您避免了需要至少使用變量和返回來設置堆棧幀的3個完整函數調用。如果你的功能比O(1)效率差,那麼差別將更加明顯。

如果有人想用不同能效等級的功能做速度測試,我會對結果感興趣,它應該有助於說明我的觀點。

+0

這非常有幫助。如果這個函數大部分時間返回零,第一個函數效率稍高一點,否則第二個函數效率更高?我想要對衝我的賭注,我最好只是使用任務的方式。 – ridthyself

+0

第二個更有效率,如果有任何小函數不會返回0,它會更好地使用任務。也是更好的風格。 –

+0

明白了。謝謝! – ridthyself