2011-10-11 173 views
4

我有一個嵌套的foreach循環,我真的需要削減計算時間。每個集合約有50個成員,因此推斷是巨大的。我查看了很多關於SelectMany的信息,但我仍然不完全確定如何使用它,或者它是否是正確的解決方案。C#嵌套的foreach循環優化

List<string> StringList; //Populated in previous code 
Type[] assemblyTypes = RandomAssembly.GetTypes(); 

foreach (String name in StringList) 
{        
    foreach (Type at in assemblyTypes) 
    {        
    if (name == at.Name) 
    {          
     //Do stuff. 
    } 
    } 
} 

在此先感謝!

回答

4

使用查找(如字典),以增加檢查類型名稱的速度:

List<string> StringList; //Populated in previous code 
Dictionary<string,Type> assemblyTypes = RandomAssembly.GetTypes() 
    .ToDictionary(t => t.Name, t => t); 

foreach (String name in StringList) 
{        
    if (assemblyTypes.ContainsKey(name)) 
    {          
     //Do stuff. 
    } 
    } 
} 

您也應該檢查這2個集合(StringListassemblyTypes)的可能更大。您通常希望將較大的一個轉換爲查找以減少迭代次數。

+1

請注意,您可能希望將其調整爲使用t.FullName,因爲在單獨的命名空間中具有公共控件的庫可能會導致字典鍵中的衝突。我的假設是OP將需要在StringList變量中解釋這一點。 –

+0

@JoelEtherton的好處,但他聲稱字符串列表來自其他地方(並正在使用'。姓名'在他的例子)我現在離開這個職位 –

+0

@SteveGreatrex這種方法似乎是正確的做法,但它仍然有點稅。 StringList最多有40個成員,並且由於需要對「do stuff」部分進行排序,因此它需要成爲父循環。減少StringList的大小會大大減少計算時間,但這不是真實世界的情況。想法? – sburke1988

0

你可以嘗試這樣的:

assemblyTypes.Where(x => StringList.Contains(x.Name)); 

請記住,這是區分大小寫,忽略空格,所以你將需要添加的情況下審議或修剪如果這是一個問題。

編輯:(例如用於循環使用)

foreach (Type item in assemblyTypes.Where(x => StringList.Contains(x.Name))) 
{ 
    // Do stuff 
} 
+0

這仍然會導致代碼在程序集中爲每種類型遍歷一次'StringList' - 字典會快得多 –

+0

@Steve Greatrex:我沒有選擇類型(OP選擇列表),但是甚至在使用字典時,您必須使用x.Keys.Contains(它與我的示例執行相同的操作),或者通過直接訪問字典項的鍵值來爲謂詞提供更多代碼。我不確定這些收益是否值得,但我會對OP的兩個基準都感興趣。 –

+0

如果您使用「Dictionary 」,則可以使用在封面下使用散列查找關鍵字的「ContainsKey」方法。特別是對於較大的集合,'ContainsKey'將大大**比迭代'Keys'集合更快** –

2

負載類型[]到字典或HashSet的(取決於你的.NET的版本),然後將內環消失。

List<string> StringList; //Populated in previous code 
Type[] assemblyTypes = RandomAssembly.GetTypes(); 
Dictionary<String,Type> typesHash = new Dictionary<String,Type>(); 
foreach (Type type in assemblyTypes) { 
    typesHash.Add(type.Name, type); 
} 

foreach (String name in StringList) {        
    Type type = null; 
    if (typesHash.TryGetValue(name, out type)) { 
    // do something with type 
    } 
} 
+0

內部循環沒有消失,它只是嵌入在散列的TryGetValue方法中。儘管如此,在循環的那部分搜索已經減少了。 –

+0

@Joel,touché:) – Lucas

0

最好的優化可能不是查詢名稱,而是查詢實現的接口。

確保您正在優化您的代碼的正確問題/部分。