我正在评估我的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
});**
答案 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
});
话虽如此,您的性能问题是您在任何地方都在使用IEnumerable
。 IEnumerable
每次使用时都可能会重新评估(取决于基础类型是什么),因此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
方法的结果类型,因此我做了一些小改动,但你可以得到要点......