Performance 为什么Linq那么慢(参见提供的示例)

Performance 为什么Linq那么慢(参见提供的示例),performance,linq,lazy-evaluation,Performance,Linq,Lazy Evaluation,这个Linq非常慢: IEnumerable<string> iedrDataRecordIDs = dt1.AsEnumerable() .Where(x => x.Field<string>(InputDataSet.Column_Arguments_Name) == sArgumentName && x.Field<string>(InputDataSet.Column_Arguments_Value)

这个Linq非常慢:

IEnumerable<string> iedrDataRecordIDs = dt1.AsEnumerable()
    .Where(x => x.Field<string>(InputDataSet.Column_Arguments_Name) == sArgumentName 
         && x.Field<string>(InputDataSet.Column_Arguments_Value) == sArgumentValue)
    .Select(x => x.Field<string>(InputDataSet.Column_Arguments_RecordID));

IEnumerable<string> iedrDataRecordIDs_Filtered = dt2.AsEnumerable()
    .Where(x => iedrDataRecordIDs.Contains(
                 x.Field<string>(InputDataSet.Column_DataRecordFields_RecordID)) 
             && x.Field<string>(InputDataSet.Column_DataRecordFields_Field) 
                 == sDataRecordFieldField 
             && x.Field<string>(InputDataSet.Column_DataRecordFields_Value) 
                 == sDataRecordFieldValue)
    .Select(x => x.Field<string>(InputDataSet.Column_DataRecordFields_RecordID));

IEnumerable<string> ieValue = dt2.AsEnumerable()
    .Where(x => x.Field<string>(InputDataSet.Column_DataRecordFields_RecordID) 
                == iedrDataRecordIDs_Filtered.FirstOrDefault() 
            && x.Field<string>(InputDataSet.Column_DataRecordFields_Field) == sFieldName)
    .Select(x => x.Field<string>(InputDataSet.Column_DataRecordFields_Value));

if (!ieValue.Any()) //very slow at this point
    return iedrDataRecordIDs_Filtered.FirstOrDefault();
你在问为什么

IEnumerable<string> iedrDataRecordIDs_Filtered = data;    
foreach (var item in collection)
{
    // do something with
    iedrDataRecordIDs_Filtered.FirstOrDefault();
}
非常简单,因为每次获得
FirstOrDefault
时,您都在评估
IEDRDataRecordId
集合。这不是一个具体的对象,而是一个可枚举集。这实际上只是一个返回一些对象的函数。每次查询时,都会调用该函数,并支付执行成本

如果你改变

IEnumerable<string> iedrDataRecordIDs_Filtered = dt2.AsEnumerable()... 
var recordIDs = iedrDataRecordIDs_Filtered.ToList();
IEnumerable IEDRDataRecordId\u Filtered=dt2.AsEnumerable()。。。
var recordIDs=iedrDataRecordIDs_Filtered.ToList();

然后使用
recordIDs.FirstOrDefault()
您将看到性能的巨大提高。

所以您建议我使用ToList()创建一个列表。如果你只需要第一个项目,那么选择第一个项目(你的第二个执行速度更快的示例)。我假设您需要在某个时候识别的所有项目,否则为什么要创建一个
IEnumerable
?re:“成本太高”-这取决于这么多东西,但是如果项目已经在内存中,那么它不会花费大量内存-只是引用-也不会花费时间。我的建议是专注于你需要做的事情!如果您只需要第一项,只需获取第一项,将其放入局部变量中,然后使用它,而不要与
IEnumerable
对象混淆。如果需要多次遍历所有项,请将它们放入列表中。
IEnumerable<string> iedrDataRecordIDs_Filtered = data;    
foreach (var item in collection)
{
    // do something with
    iedrDataRecordIDs_Filtered.FirstOrDefault();
}
string sRecordID = data.FirstOrDefault();
foreach (var item in collection)
{
    // do something with
    sRecordID;
}
IEnumerable<string> iedrDataRecordIDs_Filtered = dt2.AsEnumerable()... 
var recordIDs = iedrDataRecordIDs_Filtered.ToList();