比较数据的最有效方法

吉米

在我们的应用程序中,有一个定期调用的函数,需要将之前的调用结果与当前的调用结果进行比较,如下所示

public class Record
{
  public long Id{get;set}
  public bool SwitchStatus{get;set;}

//.....Other Fields.....
}

public class Consumer
{
  private List<Tuple<long, bool>> _sortedRecordIdAndStatus = new List<Tuple<long, bool>>();

 void IGetCalledEveryThreeSeconds(List<Record> records)
 {

    var currentsortedRecordIdAndStatus = records.Select(x=> new Tuple<long, bool> (x.Id, x.SwitchStatus)).ToList();
   if(!currentsortedRecordIdAndStatus.SequenceEqual(_sortedRecordIdAndStatus))
   {
      DoSomething();
   }

  _sortedRecordIdAndStatus  = currentsortedRecordIdAndStatus;

 }

}

当调用具有数千条记录的函数时,ToList() 函数会花费大量时间。这是目前的瓶颈。

我正在尝试优化此例程。我只需要比较一块数据是否相同

我想我只需要从传入的记录中创建一个数据块,并将该块与创建的下一个调用块进行比较……我需要知道的是该块是否相同(包括顺序)。我什至不需要查看里面的数据

例如。对于块的内容

[[1000][true]]
[[2000][false]]
[[1500][true]]

有什么办法可以优化我的代码吗?

脱衣战士

这伴随着标准警告,即过早优化是万恶之源,我只是相信你的说法,这确实是应用程序性能的瓶颈。

  1. 如果记录块有可能具有不同的长度,那么检查它们的长度比遍历它们要快得多。
  2. 如果您可以使用流式 LINQ 运算符,则可以在发现两个块不相同的那一刻短路。如果经常出现它们不相同的情况,这可以带来相当大的性能改进。
  3. 如果它没有太多的内存开销,并且如果您可以安全地假设代码的其他部分在传递给您的方法后不会更改 List,则您应该考虑只保留给您的 List而不是创造一个新的。

像这样的东西:

public class Consumer
{
 private List<Record> _previousRecords = new List<Record>();

 void IGetCalledEveryThreeSeconds(List<Record> records)
 {
    if(records.Count == _previousRecords.Count
       && records.Select(x => (x.Id, x.SwitchStatus)).SequenceEqual(
          _previousRecords.Select(x => x.Id, x.SwitchStatus))
    {
      DoSomething();
    }

    _previousRecords  = records;
 }

但是,考虑到您对输入通常相同的评论,我不知道这些优化是否会有所帮助。由于您几乎必须遍历整个列表以验证它们是否不同,无论如何,这些优化不会将事情改善一个数量级。并且很难知道避免每次创建新列表是否会抵消每次从 _previousRecords 中选择新元组的开销。

如果您真的需要从中榨取每一盎司的性能,并且您确定这是瓶颈,并且您无法提出一个更广泛的架构解决方案来首先避免这个瓶颈,那么您最后的最佳选择是可能是为了避免 LINQ 并进行for循环。但这些改进可能不足以产生业务级别的差异。

public class Consumer
{
 private List<Record> _previousRecords = new List<Record>();

 void IGetCalledEveryThreeSeconds(List<Record> records)
 {
    var length = records.Count;
    if(length != _previousRecords.Count)
    {
      return;
    }

    for(int i = 0; i < length; i++)
    {
        var record1 = records[i];
        var record2 = _previousRecords[i];
        if(record1.Id != record2.Id || record1.SwitchStatus != record2.SwitchStatus)
        {
          _previousRecords = records;
          return;
        }
    }

    DoSomething();
 }

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章