简体   繁体   English

C#嵌套的foreach循环优化

[英]C# Nested foreach loop optimization

I've got a nested foreach loop that I really need to cut the computation time on. 我有一个嵌套的foreach循环,我真的需要减少计算时间。 Each collection is at about 50 members, so the extrapolation is huge. 每个集合大约有50个成员,因此推断是巨大的。 I've looked at a lot of information about SelectMany, but I'm still not entirely sure how to use it, or if it's the correct solution. 我查看了很多关于SelectMany的信息,但我仍然不完全确定如何使用它,或者它是否是正确的解决方案。

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.
    }
  }
}

Thanks in advance! 提前致谢!

Use a lookup (such as a dictionary) to increase the speed of checking for a type name: 使用查找(例如字典)来提高检查类型名称的速度:

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.
    }
  }
}

You should also check which of the 2 collections ( StringList or assemblyTypes ) is likely to be larger. 您还应该检查2个集合( StringListassemblyTypes )中哪一个可能更大。 You generally want the larger one to be converted to the lookup in order to reduce the number of iterations. 您通常希望将较大的转换为查找以减少迭代次数。

Load Type[] into a Dictionary or HashSet (depending on your version of .NET) and then the inner loop disappears. 将Type []加载到Dictionary或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
  }
}

You might try something like: 您可以尝试以下方法:

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

Keep in mind this is case sensitive and ignores whitespace, so you will need to add case consideration or trimming if that's an issue. 请记住,这是区分大小写并忽略空格,因此如果这是一个问题,您将需要添加案例考虑或修剪。

Edit: (example for loop usage) 编辑:(循环使用示例)

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

如果您的数组/列表包含许多项,则可以尝试使用Parallel ForEach循环

The best optimization might be by querying not for the name but instead for an implemented interface. 最佳优化可能是通过查询名称而不是查询实现的接口。

Make sure you are optimizing the correct issue/part of your code. 确保您正在优化代码的正确问题/部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM