2013-04-30 192 views
0

第一種情況:哪些功能運行速度更快?

void lowTermReduction(int numerator, int denominator) { 
    int gcd = GCD(numerator, denominator); 
    numerator /= gcd; 
    denominator /= gcd; 
} 

第二種情況:

void lowTermReduction(int numerator, int denominator) { 
    int gcd = GCD(numerator, denominator); 
    if (gcd != 1) { 
     numerator /= gcd; 
     denominator /= gcd; 
    } 
} 

哪一個更高效(快速)?
在第一種情況下,功能總是執行除法,如果該除法爲1並且不會更改numeratordenominator中的值。我不知道CPU在12/1還是12/2時速度更快,但我認爲這是完全相同的。
在第二種情況下,相反,當Greater Common Divisor與1不同時,函數僅執行。但在此情況下,它執行邏輯運算if
有效率差異?如果是這樣,他們是相關的嗎?

+16

哪一種消耗更少的時間,當你異形它? – 2013-04-30 19:27:25

+5

不管怎麼說,我懷疑它是否重要。將GCD降至1所需的時間將主宰最終檢查所佔用的運行時間。 – Mysticial 2013-04-30 19:28:59

+0

我想說這種差異是可以忽略的,但是第一部分只會是最快的。 – 2013-04-30 19:31:00

回答

3

沒有一個具體的CPU架構,典型應用案例分析,很難說哪一個是速度更快。

但是,讓我們來看看兩個版本:

第一個版本:

  • 沒有「如果」,使兩個部門就一定會執行。
  • 此外,總是有兩次讀取和兩個寫入存儲器(或CPU寄存器)。

第二個版本:

  • 總有一個比較操作,這也導致在一個存儲器讀(或CPU寄存器讀取)
  • 然而,兩個分區將僅在情況下所執行的'如果'條件成立。
  • 此外,如果條件滿足,有一次兩次讀取和兩次寫入。

因此,它的實際取決於「if」條件是多久,而這又取決於用例。但是,總的來說,我會說第一個版本更快,因爲大部分時間第二個選擇中的'if'條件都會被滿足。因此,大多數情況下,您將針對'if'條件獲取一個比較操作和一個讀取操作,以及兩個讀取操作和兩個寫入操作,以及'if'塊的兩個除法操作。

1

大多數計算機的分區是CPU可以執行的最慢算術運算之一,另一方面,條件跳轉非常快(如果您現在忘記了管線問題)。

然而,首先你需要弄清楚這是否真的是你程序中的瓶頸。然後,你需要測量兩個版本的時間。

最後,我想你不會看到任何性能提升,因爲你將這個數字除以1,所以這應該是非常快的,而且你可能只會在這裏跳轉時引入問題,所以它是if版本可能會變慢。

請確保您閱讀Bill的答案this的問題。

+1

和緩存問題!有了這麼小的程序,它可能就不那麼明顯了,但是如果函數更大,那麼你可能會冒險跳到一段代碼中,這些代碼沒有從主內存加載到緩存中,迫使CPU讀取它,而無條件地部門所有相關的代碼已經在那裏。正如你所說,簡介是王道 - 即使如此,我想在不同的處理器中答案會有所不同。 – 2013-04-30 19:39:18

0

第一種情況平均會更快。原因在於,第二個功能將永遠需要進行比較,如果認爲必要,則必須進行劃分。雖然如果只執行一次或兩次,您將不會注意到其中的差異,但如果它是多次運行的更大函數的一部分,則可能會稍微更明顯。

第一個被調用時總是會執行1次操作,所以如果被調用n次,它將執行n次操作。第二個最好的情況是n次操作(如果每個呼叫的GCD都是1),但最壞的情況是2n次操作。所以我會說安全的賭注是去與第一個案件

2

答案取決於你通常會提供給你的功能的輸入。如果大多數時候GCD最終爲1,那麼第二個函數將執行更少的指令。如果GCD的大部分時間與1不同,那麼第一個函數將執行更少的指令。

此功能不太可能成爲您的系統的瓶頸。您應該剖析整個系統,並只優化真正花費最多時間的部件。

0

因爲第二個版本正在執行比較,所以第二個版本會比較慢。

問題是:慢多少?

我的猜測是時間的​​改善並不顯着。

如果你想加快程序,找出如何擺脫分裂。