2012-06-13 33 views
5

我有兩個相關的問題,一個是通用的,另一個是針對我正在開發的項目的。循環,功能設計和效率:兩個問題

  1. 通常,如果我有很多次迭代(百萬)在特定條件下被執行的代碼的某些部分的循環,豈不是更好(更有效)有一個循環多個條件語句或多個循環,而不他們。例如。

例1:

while (something()) 
{ 
    // some common code 
    if (condition_a) 
     // some code 
    if (condition_b) 
     // some code 
    // some more common code 
} 

例2:

if (condition_a && condition_b) 
{ 
    while (something()) 
    { 
     // some common and specific code 
    } 
} 
else if (condition_a) 
    while (something()) //.. 
else if (condition_b) 
    // Another loop 
else //... 

好像實施例2將導致在冗餘的成本更有效的代碼,因爲條件檢查一次,而不是百萬次。如果通用代碼很大或者有很多可能的條件,這看起來非常多餘。

  1. 現在我的具體問題。我有一個從文件中讀取點並將它們插入到數據結構中的函數。它看起來是這樣的:

    而(閱讀器 - > read_point) {// 做一些東西 //插入點 }

的問題是,有幾個函數用於讀取根據用戶提供的標準應該使用的點。例如,read_point_inside_circle(),read_point_inside_rectangle()等。

理想情況下,我想事先使用函數指針來決定正確的函數,但我不認爲這是可能的,因爲reader是一個Reader類的實例如果有可能以某種方式解決我所有的問題)。

在這種情況下,如果我有多個只有條件不同的循環,或者我應該使用多個if語句來避免冗餘代碼,

for(;;) 
{ 
    if (read_every_point) 
     if(!reader->read_point()) 
      break; 
    else if (read_inside_circle) 
     if(!reader->read_inside_circle()) 
      break; 
    else if // ... 
} 
+2

我懷疑第一個會對現代編譯器有什麼影響。我會選擇更可讀的,並讓編譯器爲我優化。 – amit

回答

2

理想我想用一個函數指針上事先正確的函數決定,但我不認爲這是可能的,因爲讀者是一個閱讀器類的一個實例(如果有可能以某種方式說將解決我所有的問題)。

可以使用成員函數指針的,假設你所有的閱讀函數具有相同簽名:

typedef void (Reader::*read_fun_t)(); 
read_fun_t read_fun = &Reader::read_point; 
// or 
read_fun_t read_fun = &Reader::read_inside_circle; 

... 

(reader->*read_fun)(); 

,或者如果你不覺得舒適與他們,您只需建立自己的自由功能,包裝的方法調用:

void read_point(Reader* reader){ reader->read_point(); } 
void read_inside_circle(Reader* reader){ reader->read_inside_circle(); } 

並使用常規函數指針代替。

+0

這確實奏效,但令人遺憾的是,我的函數使用不同的參數:read_point(),inside_circle(F64 center_x,F64 center_y,F64 radius),inside_rectangle(F64 min_x,F64 max_x,...)。 任何方法? – jaho

+0

@Marian:如果參數是_loop invariant_,那麼更高級別的函數對象和活頁夾將會執行。尋找'std | boost :: function'和'std | boost :: bind'。 –

3

要回答您的具體問題:讀取文件所花費的時間將會壓倒在if/else中花費的時間。寫任何更具可讀性。這通常更有效率,在證明它是瓶頸之前不要對其進行優化。

要回答你的一般問題:取決於很多事情,現代編譯器非常擅長於獨立於你的直覺而有效地做事。所以這是一個理論上的討論,直到你在特定的編譯器和體系結構上運行代碼。