消除.net lambda表达式

时间:2015-09-24 19:40:41

标签: c# linq lambda

我正在评估我的C#.NET Web应用程序中的性能问题,并追踪了链式lambda表达式的瓶颈。我想完全删除lambda表达式,以便我可以评估链中每个步骤的性能,但我对lambda表达式相对较新。有没有人对如何将第二个lambda express重构为更传统的代码有任何想法,以便可以跟踪每个步骤或操作?

IEnumerable<OurPerformance> validPerformances = package.TimeFilteredValidPerformances(visitDateAndTime);

IEnumerable<WebPerformance> webPerformances = performanceGroup.RegularNonPassedPerformances
            .Where(performance => validPerformances.Select(perf => perf.PerformanceId).Contains(performance.PerformanceId))                
            .Select(performance =>
                new WebPerformance
                {
                    Date = performance.PerformanceDate.ToJavaScriptDateString(),
                    PerformanceId = performance.PerformanceId,
                    Title = performance.UserFriendlyTitle,
                    ProductionSeasonId = performance.ProductionSeasonId,
                    AvailableCount = performance.AvailableCount
                });

**IEnumerable<WebProduction> webProductions = webPerformances
            .GroupBy(performance => performance.ProductionSeasonId)
            .ToDictionary(grouping => SheddProduction.GetOurProduction(grouping.Key), grouping => grouping.ToList())
            .Select(perfsByProduction =>
                new WebProduction
                {
                    ProductionSeasonId = perfsByProduction.Key.ProductionSeasonNumber,
                    Duration = perfsByProduction.Key.Duration,
                    Title = perfsByProduction.Key.UserFriendlyTitle,
                    Synopsis = perfsByProduction.Key.UserFriendlySynopsis,
                    ThumbnailImage = perfsByProduction.Key.PreviewImage,
                    Performances = perfsByProduction.Value
                });**

3 个答案:

答案 0 :(得分:2)

我不能建议任何算法来排除lambda表达式,但我有另一个建议。尝试使用List for webPerformances而不是IEnumerable集合。 调用ToList()获取List webPerformances。在这种情况下,第二个lambda表达式将与list一起使用,不会重新评估IEnumerable集合。

答案 1 :(得分:1)

它实际上相当简单,将其分解为更小的部分,这些部分更明显地转化为传统的&#34;码。只需将每个linq表达式结果存储在一个局部变量中,如下所示:

var groupedWebPerformances = webPerformances.GroupBy(performance => performance.ProductionSeasonId);
var webPerformancesDictionary = groupedWebPerformances .ToDictionary(grouping => SheddProduction.GetOurProduction(grouping.Key), grouping => grouping.ToList());
IEnumerable<WebProduction> webProductions = webPerformancesDictionary.Select(perfsByProduction =>
                new WebProduction
                {
                    ProductionSeasonId = perfsByProduction.Key.ProductionSeasonNumber,
                    Duration = perfsByProduction.Key.Duration,
                    Title = perfsByProduction.Key.UserFriendlyTitle,
                    Synopsis = perfsByProduction.Key.UserFriendlySynopsis,
                    ThumbnailImage = perfsByProduction.Key.PreviewImage,
                    Performances = perfsByProduction.Value
                });

话虽如此,您的性能问题是您在任何地方都在使用IEnumerableIEnumerable每次使用时都可能会重新评估(取决于基础类型是什么),因此validPerformances会对RegularNonPassedPerformances中的每个项目以及每个项目重新评估webPerformances在整个枚举被强制评估之前,validPerformances.Select(perf => perf.PerformanceId).Contains(performance.PerformanceId) 没有得到评估,所以性能问题似乎是稍后但很可能在这里:

ToList

确保在创建这些枚举时List<OurPerformance> validPerformances = package.TimeFilteredValidPerformances(visitDateAndTime).ToList(); List<WebPerformance> webPerformances = performanceGroup.RegularNonPassedPerformances .Where(performance => validPerformances.Select(perf => perf.PerformanceId).Contains(performance.PerformanceId)) .Select(performance => new WebPerformance { Date = performance.PerformanceDate.ToJavaScriptDateString(), PerformanceId = performance.PerformanceId, Title = performance.UserFriendlyTitle, ProductionSeasonId = performance.ProductionSeasonId, AvailableCount = performance.AvailableCount }) .ToList(); List<WebProduction> webProductions = webPerformances .GroupBy(performance => performance.ProductionSeasonId) .ToDictionary(grouping => SheddProduction.GetOurProduction(grouping.Key), grouping => grouping.ToList()) .Select(perfsByProduction => new WebProduction { ProductionSeasonId = perfsByProduction.Key.ProductionSeasonNumber, Duration = perfsByProduction.Key.Duration, Title = perfsByProduction.Key.UserFriendlyTitle, Synopsis = perfsByProduction.Key.UserFriendlySynopsis, ThumbnailImage = perfsByProduction.Key.PreviewImage, Performances = perfsByProduction.Value }) .ToList(); 强制执行$ gfortran fengdemo.F fengdemo.F:1:0: #include "fintrf.h" ^ Fatal Error: fintrf.h: No such file or directory compilation terminated. 时,强制所有可枚举因素评估一次:

locate

答案 2 :(得分:1)

这是lamba-refactoring你的第二个lambda表达式&#34;传统&#34;代码:

IEnumerable<IGrouping<string, WebProduction>> groupedPerformances 
    = webPerformances.GroupBy(performance => performance.ProductionSeasonId);

var dictionary = new Dictionary<string, List<WebProduction>>();
foreach (IGrouping<string, WebProduction> grouping in groupedPerformances)
{
    var group = new List<WebProduction>();
    foreach (WebProduction webProduction in grouping)
        group.Add(webProduction);

    dictionary.Add(grouping.Key, group);
}

var result = new List<WebProduction>();
foreach (KeyValuePair<string, List<WebProduction>> item in dictionary)
{
    var wp = new WebProduction
    {
        ProductionSeasonId = perfsByProduction.Key.ProductionSeasonNumber,
        Duration = perfsByProduction.Key.Duration,
        Title = perfsByProduction.Key.UserFriendlyTitle,
        Synopsis = perfsByProduction.Key.UserFriendlySynopsis,
        ThumbnailImage = perfsByProduction.Key.PreviewImage,
        Performances = perfsByProduction.Value
    };
    result.Add(wp);
}

我不知道你SheddProduction.GetOurProduction方法的结果类型,因此我做了一些小改动,但你可以得到要点......