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;
}
有什么方法可以优化我的代码吗?这是标准的警告,过早优化是万恶之源,我相信你的说法,这确实是应用程序性能的瓶颈
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;
}
这是标准的警告,过早优化是万恶之源,我相信你的说法,这确实是应用程序性能的瓶颈
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();
}