2011-10-11 120 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

最好的优化可能不是查询名称,而是查询实现的接口。

确保您正在优化您的代码的正确问题/部分。