我有一个定义如下的类:
public class AlarmViolation
{
public string ObjectId { get; set; }
public int ChartType { get; set; }
public string AlarmInternalId { get; set; }
public short PositionInSequence { get; set; }
public short SequenceCount { get; set; }
public string TagValue { get; set; }
public DateTime PurgeDate { get; set; }
}
然后我按如下方式创建此类的List:
List<AlarmViolation> alarmViolationList;
我目前执行Linq查询,如下所示:
return alarmViolationList
.Where(row => row.ObjectId == objectId)
.Where(row => row.ChartType == this.ChartType)
.Where(row => row.AlarmInternalId == this.InternalId)
.Where(row => row.PositionInSequence == positionInSequence)
.Where(row => row.SequenceCount == sequenceCount)
.Any();
我的当前实现性能相当糟糕。该列表通常包含介于150K和300K之间的条目。此查询定期执行数百次(大约每3分钟执行一次)。
如果我可以以某种方式索引此列表,或者如果这是一个数据库表,我将在ObjectId + ChartType上创建一个索引。
有人可以建议更有效的实施。如果您需要更多信息,我很乐意提供。
答案 0 :(得分:3)
如果我可以以某种方式索引此列表,或者如果这是一个数据库表,我将在ObjectId + ChartType上创建一个索引。
这表明你应该创建一个由ObjectId和ChartType组成的密钥类型(AlarmViolationKey
?),然后使用Dictionary<AlarmViolationKey, AlarmViolation>
。这将从根本上增强搜索时间。如果每个密钥有多个违规行为,和您已预先创建了一个不会更改的列表,则可以使用Lookup
代替。< / p>
无论你做什么,基本上你不想做你正在做的线性扫描 - 你想要一个基于散列的查找。
(根据您的具体情况,您可能仍需要一个列表,或者您可以完全使用字典而不是列表。如果没有更多上下文,很难说。)
答案 1 :(得分:1)
由于您只搜索相等性,我建议您使用哈希表。创建一个类,它将包含您在相同位置搜索的所有成员(在您的情况下:ObjectId,ChartType,AlarmInternalId,...)。实施Equals
和GetHashCode
。
接下来,使用Enumerable.ToDictionary
或Enumerable.ToLookup
将所有对象放入查找表中。您可以使用新创建的“密钥”类添加项目并搜索项目。
这将为您提供持续的时间查找,即使是多个结果也是如此。
答案 2 :(得分:0)
你为什么不写这个:
return alarmViolationList
.Any(row => row.ChartType == this.ChartType && //int
row.PositionInSequence == positionInSequence && //short
row.SequenceCount == sequenceCount && //short
row.AlarmInternalId == this.InternalId && //string
row.ObjectId == objectId); //string
在我看来,这应该可以提高一些性能。请注意,我正在进行string
比较 int
和short
比较之后,利用短路。