2010-11-24 37 views
1

假設我正在使用C++。現在,我有以下代碼:在這種情況下,如何優化性能而不違反DRY(不重複自己)原則?

int flag; 
// ... 
while (!TimeToExitLoop()) { 
    Func(); 
} 

while循環將被執行的時間數量龐大,而且Func是這樣一個時間關鍵功能:

void Func() { 
    // some big stuff ... 
    if (flag > 1) { 
     // logic 1 ... 
    } 
    else { 
     // logic 2 ... 
    } 
} 

而且,flag值將不會在while循環內發生變化。因此,最好是移動條件if聲明瞭while循環,並定義兩個單獨的函數的兩個條件是這樣的:

int flag; 
// ... 
if (flag > 1) { 
    while (!TimeToExitLoop()) { 
     Func_FlagBiggerThanOne(); 
    } 
} 
else { 
    while (!TimeToExitLoop()) { 
     Func_FlagNoBiggerThanOne(); 
    } 
} 

然而,這將導致「大東西」的重複在Func通過Func_FlagBiggerThanOneFunc_FlagNoBiggerThanOne

void Func_FlagBiggerThanOne() { 
    // big stuff ... 
    // logic 1 ... 
} 

void Func_FlagNoBiggerThanOne() { 
    // big stuff ... 
    // logic 2 ... 
} 

這將違反鴕鳥政策重複自己動手的原則。我們不能在某些函數中使用「大東西」,因爲調用該函數會比原始語句更費時。其中一個解決方案是爲那個大東西定義一個宏,但是如果「邏輯1」和「邏輯2」將使用「大東西」中定義的變量呢?雖然宏仍然有效,但這可能會導致難看的代碼,程序的讀者可能會想,「這些變量在哪裏定義?」

+0

使用一個編譯器/鏈接器,它可以將條件從環路中斷開......但編譯器/鏈接器必須是相當的如果`Func`在另一個文件中,因爲`flag`顯然是全局性的,所以很時髦。 – lijie 2010-11-24 11:01:56

+1

「我們不能在某些函數中放入那些」大東西「,因爲調用該函數比原始if語句耗時更多。 » 你不能內聯嗎? – Zecc 2010-11-24 11:23:27

+0

我認爲一個好的程序員不應該從編譯器/鏈接器中取任何東西。另外,Zecc,我猜內聯不會工作,因爲那些東西非常「大」。 – 2010-11-25 05:11:40

回答

0

我們不能把那個「大東西」在 一些功能,因爲調用該 功能會消耗更多的時間 比原來的if語句。

我有一個最喜歡的古英語成語:「便士英鎊愚蠢」(我已經有罪)。另一種說法是「不要爲小東西出汗」。 我希望我能找到SO上的原始報價:「讓理髮減肥」。

使代碼乾淨,如果你可以合理地遵循DRY,那就這樣做。 然後做你的性能調整。 This is how I do it. 如果調用該函數的成本或IF語句的成本甚至上升到雷達上,我會感到非常驚訝。

0

我只想到一個解決方案。其主要思想是利用#ifdef

#define FUNC() do { \ 
    // big stuff ... 
#ifdef FLAG_BIGGER_THAN_ONE \ 
    // logic 1 ... \ 
#else \ 
    // logic 2 ... \ 
#endif \ 
} while(0) 

所以我們可以這樣寫的主要邏輯是這樣的:

int flag;    
// ...    
if (flag > 1) {    
    while (!TimeToExitLoop()) { 
#define FLAG_BIGGER_THAN_ONE    
     FUNC(); 
#undef FLAG_BIGGER_THAN_ONE    
    }    
}    
else {    
    while (!TimeToExitLoop()) {    
     FUNC();    
    }    
} 

然而,正如邁克建議,「這是更好地認爲,相對而言,而不是如果「大東西」無法調整,這樣的優化將毫無用處

相關問題