【问题标题】:How can I execute this System.Linq statement faster?如何更快地执行此 System.Linq 语句?
【发布时间】:2020-02-05 19:22:05
【问题描述】:

我有一个自定义类的可枚举,我正在使用它的子集,如下所示:

var sourceSet = await GetSourceSetData(inputParam1, inputParam2);

_logger.Info.Write(message: "CheckpointA");

var resultSet = sourceSet.Where(x => (x.Property1 + x.Property2 > 0) ||
                                     (!myBoolean && x.Property3.SubProperty > x.Property4));

_logger.Info.Write(message: "CheckpointB");

GetSourceData 由多个数据库调用组成...

var dataTask1 = _db.GetThisData(inputList);
var dataTableForTVP = GetCutoffDates(inputList, myBoolean).CopyToDataTable();
var dataTask2 = _db.GetThatData(dataTableForTVP, myBoolean);
var dataTask3 = _db.GetMoreData(inputList, myBoolean);
var dataTask4 = _db.GetEvenMoreData(inputList);
var dataTask5 = _db.GetMoarMoreData(inputList);

var task1Result = await dataTask1;
var task2Result = await dataTask2;
var task3Result = await dataTask3;
var task4Result = await dataTask4;
var task5Result = await dataTask5;

var sourceSuperSet = inputList.Select(x => new MyCustomClass()
{
    IdProperty = x.IntProperty,
    CategoryProperty = 0,
    PropertyY = task1Result.FirstOrDefault(y => y.IdProperty == x.IntProperty) == null ? 0.00m : task1Result.FirstOrDefault(y => y.IdProperty == x.IntProperty).DecimalProperty,
    Property3 = task2Result.FirstOrDefault(z => z.IdProperty == x.IntProperty) ?? new FourPropertyClass() {IdProperty = x.IntProperty, DecProperty1 = 0, DecProperty2 = 0},
    PropertyU = task3Result.FirstOrDefault(u => u.IdProperty == x.IntProperty) == null ? 0.00m : task3Result.FirstOrDefault(u => u.IdProperty == x.IntProperty).DecimalProperty,
    PropertyV = task4Result.FirstOrDefault(v => v.IdProperty == x.IntProperty) == null ? 0.00m : task4Result.FirstOrDefault(v => v.IdProperty == x.IntProperty).DecimalProperty,
    PropertyW = task5Result.FirstOrDefault(w => w.IdProperty == x.IntProperty) == null ? 0.00m : task5Result.FirstOrDefault(w => w.IdProperty == x.IntProperty).DecimalProperty
});

return sourceSuperSet.Where(x => x.Property3.DecPropertyCalc > 0 &&
                                (x.Property3.DecProprtyCalc - x.PropertyY > 0.0m || 
                                 x.PropertyW - x.PropertyV > 0.0m)
                           );

从检查点 A 到检查点 B 需要很长时间(比如 12 分钟),而仅枚举中的几千个项目。获得我想要的结果的更好方法是什么?提前致谢。

【问题讨论】:

  • 这是在和数据库对话吗?你能在对其执行 Linq 操作之前将其具体化为一个列表吗?
  • 是的,这也是我的第一个想法。 sourceSet是什么类型的?
  • 您的 Property#s 是否在 get{} 部分执行任何操作?
  • edit这个问题显示用于将“数据”分配给sourceSet的语句。换句话说:sourceSet = 的右侧是什么?如果该作业使用其他来源,请同时显示这些作业。如果我们能看到MyCustomClass 的定义也会有所帮助。
  • 我不是在问类型。 Property1 是简单地返回一个值,还是进行一些计算或其他事情。没有其他理由为什么您的代码会运行缓慢。在它运行时,点击“Break All”调试器,看看它在哪里停止。

标签: c# performance linq


【解决方案1】:

您可以使用 LINQ ToLookup 方法来创建辅助数据的查找:

var task1Lookup = task1Result.ToLookup(x => x.IdProperty);
var task2Lookup = task2Result.ToLookup(x => x.IdProperty);
var task3Lookup = task3Result.ToLookup(x => x.IdProperty);
var task4Lookup = task4Result.ToLookup(x => x.IdProperty);
var task5Lookup = task5Result.ToLookup(x => x.IdProperty);

var sourceSuperSet = inputList.Select(x => new MyCustomClass()
{
    IdProperty = x.IntProperty,
    CategoryProperty = 0,
    PropertyY = (task1Lookup[x.IntProperty].FirstOrDefault()?.DecimalProperty).GetValueOrDefault(0.00m),
    Property3 = (task2Lookup[x.IntProperty].FirstOrDefault()?.DecimalProperty).GetValueOrDefault(0.00m),
    PropertyU = (task3Lookup[x.IntProperty].FirstOrDefault()?.DecimalProperty).GetValueOrDefault(0.00m),
    PropertyV = (task4Lookup[x.IntProperty].FirstOrDefault()?.DecimalProperty).GetValueOrDefault(0.00m),
    PropertyW = (task5Lookup[x.IntProperty].FirstOrDefault()?.DecimalProperty).GetValueOrDefault(0.00m),
});

【讨论】:

    猜你喜欢
    • 2019-11-18
    • 2014-03-19
    • 1970-01-01
    • 1970-01-01
    • 2017-07-15
    • 1970-01-01
    • 2021-09-17
    • 1970-01-01
    • 2019-08-24
    相关资源
    最近更新 更多