【问题标题】:How to convert the below 2 foreach nested loops to linq query?如何将以下 2 个 foreach 嵌套循环转换为 linq 查询?
【发布时间】:2014-03-16 14:51:31
【问题描述】:

如何将以下 2 个 foreach 嵌套循环转换为 LINQ 查询?执行这个包含大约 610 个项目的循环大约需要 10 秒。另外,下面的代码行是否有任何更新可以更改,从而可以稍微提高性能并减少执行时间?

代码:

foreach(var map in infoMap)
{
    var testItem = map.TestItem;
    var testInViews = TestviewMaps;
    var testWorkbenchItem = map.TestWorkbenchItem;
    string TestLinkType = string.Empty;
    WorkItemLinkCollection testLinkedWorkItems = testItem.WorkItemLinkHistory;
    if (linkedWorkItems != null && linkedWorkItems.Count > 0)
        TestLinkType = linkedWorkItems[0].LinkTypeEnd.LinkType.ReferenceName;
    else if (testItem != null)
        TestLinkType = testItem.Store.WorkItemLinkTypes.LinkTypeEnds["Parent"].LinkType.ReferenceName;
    foreach (var testViewMap in testInViews)
    {
        if (!string.IsNullOrEmpty(TestLinkType))
        {
            var testLinkName = TestLinkType;
            var testChildType = testViewMap.ChildType;

            ITestLinkItem testItm = Factory.BuildLinkItem(testLinkName,testWorkbenchItem,testWorkbenchItem);
            lock (TestAddparents)
            {
                TestAddparents.Add(testItm);
            }
            break;
        }
    }
}

【问题讨论】:

  • LINQ 不是可以立即让您的代码运行得更快的黑魔法。
  • @ken2k,或者任何其他方式,可以减少代码的执行时间。
  • @ken2k - 实际上有几篇文章由于它提供的可能性,LINQ 代码将需要更长的时间来执行,而不是更具体的每个查询

标签: .net linq c#-4.0 foreach parallel.foreach


【解决方案1】:

要回答实际问题(根据cmets)-如何提高性能,如果我们不知道代码的原因是完全不可能的。

但我注意到了一些事情:

  1. 你的循环中有一个永远不会改变的 if 条件 if (!string.IsNullOrEmpty(TestLinkType)) => 把它拿出来
  2. 您只运行了一次循环,那么为什么首先要有一个循环,只需获取第一项。

新代码可能如下所示:

    foreach(var map in infoMap)
    {
        var testItem = map.TestItem;
        var testInViews = TestviewMaps;
        var testWorkbenchItem = map.TestWorkbenchItem;
        string TestLinkType = string.Empty;
        WorkItemLinkCollection testLinkedWorkItems = testItem.WorkItemLinkHistory;
        if (linkedWorkItems != null && linkedWorkItems.Count > 0)
            TestLinkType = linkedWorkItems[0].LinkTypeEnd.LinkType.ReferenceName;
        else if (testItem != null)
            TestLinkType = testItem.Store.WorkItemLinkTypes.LinkTypeEnds["Parent"].LinkType.ReferenceName;

        if (!string.IsNullOrEmpty(TestLinkType))
        {
            var testViewMap = testInViews.FirstOrDefault();

            if (testViewMap != null)
            {
                var testLinkName = TestLinkType;
                var testChildType = testViewMap.ChildType;

                ITestLinkItem testItm = Factory.BuildLinkItem(testLinkName,testWorkbenchItem,testWorkbenchItem);
                lock (TestAddparents)
                {
                    TestAddparents.Add(testItm);
                }                    
            }
        }
    }

现在实际的问题是,时间损失在哪里,从 getter 获取值需要多长时间,您是否在执行任何数据库调用或对外部进程的调用需要很长时间?在这种情况下,您应该一次检索尽可能多的数据并将其缓存。

【讨论】:

  • 另外,我用Parallel.ForEach代替ForEach,现在执行上面的代码只需要5秒,谢谢。
猜你喜欢
  • 1970-01-01
  • 2020-12-07
  • 2011-06-07
  • 2017-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-16
  • 2014-03-17
相关资源
最近更新 更多