.net大型for循环速度减慢

Ale*_*lex 5 .net c# asynchronous

我有一个大型 for 循环(最大 30k 迭代),它似乎一直在减慢速度:

  • 前一千次迭代需要 1.34 秒
  • 12k 次迭代后,下 1000 次迭代需要 5.31 秒
  • 23k 次迭代后,下 1000 次迭代需要 6.65 秒
  • 最后一千次迭代耗时 7.43 秒

为了获得一点性能,我从一个foreach循环切换到另一个循环,并尝试了发布配置,但我在这个问题for中找不到任何其他适用于我的内容。循环位于异步方法中

为什么循环速度变慢?可以避免吗?

for(int iter = 0; iter < LargeList1.Count; iter++)
{
    var cl_from = LargeList1[iter];
    if(LargeList2.Any(cl => cl.str.Contains(cl_from.str)))
    {
        DateTime dt1 = //last write time of a file
        DateTime dt2 = //last write time of a different file
        if(DateTime.Compare(dt1, dt2) > 0)
        {
            try
            {
                CopyFile(//Kernel32 CopyFile a file overwrite);
                globals.fileX++;
            }
            catch(Exception filexx)
            {
                //error handler
            }
        }
        else
        {
            globals.fileS++;
        }
    }
    else
    {
        Directory.CreateDirectory(//create a directory, no check if it already exists);
        try
        {
            CopyFile(//Kernel32 CopyFile a file do not overwrite);
            globals.fileX++;
        }
        catch(Exception filex)
        {
            // error handler
        }

    }
    gui.UpdateCount(globals.fileF, globals.fileX, globals.fileS); //updates iteration on textboxes
    float p = (float)100.0*((float)globals.fileF + (float)globals.fileX + (float)globals.fileS)/(float)globals.totalCount;
    gui.setProgress(p); //updates progressbar
}
Run Code Online (Sandbox Code Playgroud)

编辑:正如许多人所建议的,使用 hashset.Contains(cl_from.str) 解决了问题。

Mic*_*han 4

我可以想象这两项的性质将成为瓶颈。

for(int iter = 0; iter < LargeList1.Count; iter++)
{
    .....
    if(LargeList2.Any(cl => cl.str.Contains(cl_from.str)))
    ...........
Run Code Online (Sandbox Code Playgroud)

您正在检查当前字符串中是否包含另一个大列表中的任何单词。

随着时间的推移,它可能会变慢的几个原因:

  1. 最初它的速度更快,因为 GC 运行得不多,随着循环的深入,GC 必须越来越频繁地收集。
  2. 字符串的长度cl_from.st可能会变大吗?

需要考虑的一些要点:

  1. cl_from.str和有多大LargeList2,是否值得创建 中所有可能值的哈希cl_from.str,然后检查是否有查找,甚至可能创建所有 LargeList2 字符串的哈希集,然后使用它,迭代 中字符串的每个组合cl_From.str

  2. 您可能想改进您的搜索算法,例如查看C# .NET: FASTEST WAY TO CHECK IF A OCCURS IN A STRING。或者用谷歌搜索其他字符串搜索索引/算法。为什么不使用 Lucene.NET 之类的东西?

  3. 使用 .NET 分析器找出瓶颈所在以及在哪里花费了时间。