Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 比较数据的最有效方法_C# - Fatal编程技术网

C# 比较数据的最有效方法

C# 比较数据的最有效方法,c#,C#,在我们的应用程序中,有一个周期性调用的函数,需要将以前的调用结果与当前的调用结果进行比较,如下所示 public class Record { public long Id{get;set} public bool SwitchStatus{get;set;} //.....Other Fields..... } public class Consumer { private List<Tuple<long, bool>> _sortedRecordIdA

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

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;

 }

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

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

  • 如果记录块有可能具有不同的长度,那么检查它们的长度要比遍历它们快得多
  • 如果可以使用流LINQ操作符,则可以在注意到两个块不相同时短路。如果它们经常不一样,那么这可以大大提高性能
  • <> LI>如果内存开销不太大,如果您认为代码的其他部分在传递到您的方法之后不会更改列表,那么您应该考虑只挂在您所给出的列表上而不是创建一个新的列表。 大概是这样的:

    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;
     }
    

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

  • 如果记录块有可能具有不同的长度,那么检查它们的长度要比遍历它们快得多
  • 如果可以使用流LINQ操作符,则可以在注意到两个块不相同时短路。如果它们经常不一样,那么这可以大大提高性能
  • <> LI>如果内存开销不太大,如果您认为代码的其他部分在传递到您的方法之后不会更改列表,那么您应该考虑只挂在您所给出的列表上而不是创建一个新的列表。 大概是这样的:

    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;
     }
    

    我会在类上使用ICompare方法。参见msdn:两个区块的相同频率如何?是这样的情况下,您几乎总是“做一些事情”,还是大多数块重复,而您只是偶尔“做一些事情”?如果这是一个性能问题,那么我将避免使用LINQ。执行一个简单的for循环并手动比较元素。这避免了分配和虚拟的电话来进行简单的比较。遵循医生的建议:如果疼痛,就不要这样做。使用ToList()没有意义,SequenceEquals()不需要它。我会在类上使用ICompare方法。参见msdn:两个区块的相同频率如何?是这样的情况下,您几乎总是“做一些事情”,还是大多数块重复,而您只是偶尔“做一些事情”?如果这是一个性能问题,那么我将避免使用LINQ。执行一个简单的for循环并手动比较元素。这避免了分配和虚拟的电话来进行简单的比较。遵循医生的建议:如果疼痛,就不要这样做。使用ToList()没有意义,SequenceEquals()不需要它。仅供参考,它们通常是相同的。很少有不同,谢谢你。是的,我会按照你说的提前退出策略。我不太确定是否保留这份名单。这个调用是来自另一个类的,它是一个重复使用的列表,所以不能保存到引用。如果你不能坚持你所给的列表,但是输入很少改变,你可能只考虑在给定的列表(或者它的ID/LwitcStury元组)创建一个副本之后再验证它是不同的。这将在项目不同的情况下增加一点开销(特别是如果它们开始时相同且长度相同),但当它们相同时,这将节省大量分配。仅供参考,它们通常是相同的。很少有不同,谢谢你。是的,我会按照你说的提前退出策略。我不太确定是否保留这份名单。这个调用是来自另一个类的,它是一个重复使用的列表,所以不能保存到引用。如果你不能坚持你所给的列表,但是输入很少改变,你可能只考虑在给定的列表(或者它的ID/LwitcStury元组)创建一个副本之后再验证它是不同的。在项目不同的情况下,这会增加一点开销(特别是如果它们的开头相同且长度相同),但当它们相同时,这将节省大量的分配。
    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();
     }