2

我有一个定义如下的类:

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<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 上创建一个索引。

有人可以提出更有效的实施方案。如果您需要更多信息,我很乐意提供。

4

3 回答 3

3

如果我能以某种方式索引这个列表,或者如果这是一个数据库表,我会在 ObjectId + ChartType 上创建一个索引。

这表明您应该创建一个AlarmViolationKey由 ObjectId 和 ChartType 组成的键类型 (?),然后使用Dictionary<AlarmViolationKey, AlarmViolation>. 这将从根本上增加搜索时间。如果每个键有多个违规行为,并且您已经以不会更改的方式预先创建了列表,则可以使用 aLookup代替。

无论你做什么,基本上你都不想做你当前正在做的线性扫描——你想要一个基于散列的查找。

(根据您的具体情况,您可能仍然需要一个列表,或者您可以完全使用字典而不是列表。没有更多上下文很难说。)

于 2012-08-18T19:43:46.997 回答
1

由于您只搜索相等性,我建议您使用哈希表。创建一个将包含您平等搜索的所有成员的类(在您的情况下:ObjectId,ChartType,AlarmInternalId,...)。实施EqualsGetHashCode

Enumerable.ToDictionary接下来,使用或将所有对象放入查找表中Enumerable.ToLookup。您可以使用新创建的“键”类来添加项目并搜索项目。

这将为您提供恒定的时间查找,即使是多个结果。

于 2012-08-18T19:44:33.767 回答
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比较和比较。 intshort

于 2012-08-18T19:43:43.907 回答