2011-02-16 29 views
0

在線程內調用遞歸函數是一個好主意嗎? 我正在創建10個線程,線程函數依次調用遞歸函數。壞的部分是線程內的遞歸

ThreadFunc() 
{ 
    for(;condn ; ) 
    recursiveFunc(objectId); 
} 


bool recursiveFunc(objectId) 
{ 
    //Get a instance to the database connection 

    // Query for attibutes of this objectId 

    if (attibutes satisfy some condition) 
     return true; 
    else 
     recursiveFunc(objectId) // thats the next level of objectId 
} 

遞歸函數到數據庫 我的猜測是,一個循環內遞歸函數的調用導致性能下降幾個電話。任何人都可以確認

+0

您可以提供有關遞歸函數的更多信息嗎? – sunmoon 2011-02-16 11:44:27

回答

1

沒有技術上的原因,這是行不通的 - 這是完全合法的。

爲什麼這段代碼是「壞的部分」?

您需要調試/配置此文件和recursiveFunc以查看性能下降的位置。

通過您發佈的代碼,您檢查了condn是否滿足以至於您的循環終止。如果沒有,它將永遠循環。

另外recursiveFunc實際上是做什麼的?

UPDATE

基於您的評論,每個線程執行15000次迭代我做的第一件事將是移動Get an instance to the database connection代碼recursiveFunc讓你只每個線程得到它一次。

即使你重寫成一個循環(按照Martin B的回答),你仍然會想要這樣做。

+0

當我在for循環之後調用遞歸函數時,性能很好 – 2011-02-16 11:52:09

+0

@sameer:在那種情況下,您是否研究過for循環執行多少次迭代?你的問題可能在於那裏,而不是用`recursiveFunc`本身。 – 2011-02-16 12:15:18

0

這取決於遞歸函數如何與數據庫交談。如果每個(或很多)遞歸級別重新打開可能成爲降級原因的數據庫。如果它們都與數據庫共享同一個「連接」,則問題不在於遞歸,而在於併發訪問數據庫的線程數。

0

我在發佈的代碼中看到的唯一潛在問題是它可能表示無限循環,而這通常不是您想要的(所以您必須在已知可達條件下強制中斷以避免必須發生異常應用程序爲了突破線程(以及隨後的線程)

由於各種原因,線程,遞歸和數據庫訪問都會發生性能下降 是否有任何或全部錯誤你的問題是不可能從你向我們展示的那一點確定的。

2

在一個線程內遞歸調用一個函數並不是一個壞主意本身。你唯一需要注意的是限制遞歸深度,否則你可能會產生一個(等待它......)堆棧溢出。這不是特定於多線程,但適用於使用遞歸的任何情況。

在這種情況下,我會建議不要遞歸,因爲它不是必需的。你的代碼是tail recursion的一個例子,它總是可以用循環替換。這消除了堆棧溢出問題:

bool recursiveFunc(objectId) 
{ 
    do 
    { 
     // Get an instance to the database connection 

     // Query for attributes of this objectId 

     // Update objectId if necessary (not sure what the "next level of objectId" is) 
    } 
    while(! attributes satisfy some condition); 

    return true; 
}