2011-04-04 57 views
2

我們的項目目前使用2種方法在頁面內查找控件。 第一種是遞歸使用。FindControl。 另一種是使用LINQ這樣的:ASP.Net中哪個更快?

(from n in Page.Controls.Cast<Control>().Descendants(c => c.Controls.Cast<Control>()) 
where (n as Label != null && n.ID == "TaskIDLabel") 
select n).First() as Label; 

使用這個擴展:

static public IEnumerable<T> Descendants<T>(this IEnumerable<T> source, 
              Func<T, IEnumerable<T>> DescendBy) 
{ 
    foreach (T value in source) 
    { 
     yield return value; 

     foreach (T child in DescendBy(value).Descendants<T>(DescendBy)) 
     { 
      yield return child; 
     } 
    } 
} 

其中的這2種方法比較好?哪個更快?

+2

因爲一個建立在另一個之上,所以它們都不會更好。 – 2011-04-04 16:24:27

+4

測試並找出答案。 – Jess 2011-04-04 16:28:14

+2

@Justin - 我認爲OP在詢問'FindControl'與問題中發佈的代碼相比。 – Greg 2011-04-04 16:38:00

回答

1

您的代碼和FindControl在功能上有所不同。 他們不這樣做。

FindControl不執行深層搜索,而您的代碼卻執行。從MSDN

只有當控件被指定容器直接包含時,此方法纔會查找控件;也就是說,該方法不會搜索整個控件內控件的層次結構。

哪個更好?這取決於。如果你不知道控件在頁面上的位置,那麼你的遞歸方法可以找到它。

但是,假定在Panel(ID =「MyPanel」)中有兩個控件:自定義UserControl(ID =「MyControl」)和標籤(ID =「MyName」)。如果你調用MyPanel.FindControl(「MyName」),你會在面板中找回預期的標籤。如果你使用你的函數,它將首先在MyControl中搜索ID =「MyName」的標籤。因此,如果MyControl恰好也包含ID =「MyName」的標籤,它將被返回。如果一個控件碰巧生成一個與您正在查找的ID相同的子控件,這可能是意料之外的。

至於性能,您的方法執行更深入的搜索,因此它有可能成爲一個更昂貴的操作。

+0

你的回答是不完全反映**閱讀OP詢問的問題... – 2011-04-04 16:44:19

+0

@Chris - 怎麼這樣? – Greg 2011-04-04 16:50:35

+1

Op說他使用FindControl()遞歸,而不是它自己遞歸。 – 2011-04-04 17:16:43

3

我可以進行測試,然後找出秒錶類是快速和易於使用,並會在大約30秒的努力中準確告訴你需要知道什麼。讓我們知道你發現了什麼。

http://www.dotnetperls.com/stopwatch

http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx

我建議要麼在每一個秒錶的末尾添加斷點或只是使用輸出作爲的Response.Write你只調試的值。

編輯: 您是否確實已經注意到任何性能問題,或者您是否嘗試標準化並確保選擇正確的方法?

如果您使用的是.Net 4,具體取決於控件的數量,您可以查看使用並行擴展來快速遍歷列表,這可能有所幫助。查找「AsParallel()」

1

這是一個簡單的答案,但我會說你的手寫代碼生成的IL代碼可能非常類似於FindControl使用的代碼。然而,一個主要區別是,Microsoft代碼通常針對CLR進行了非常優化,以利用大量編譯器提示來執行比大多數手寫代碼更快的執行。

所以我會親自使用FindControl進行遞歸調用。