哪个在.NET中更快,.Contains()或.Count()?

Dav*_*N59 9 .net c# linq

我想将一组修改过的记录与从数据库中提取的记录列表进行比较,并从数据库中删除那些在传入数组中不存在的记录.修改后的数组来自维护数据库的客户端应用程序,此代码在WCF服务应用程序中运行,因此如果客户端从数组中删除记录,则应从数据库中删除该记录.以下是示例代码段:

public void UpdateRecords(Record[] recs)
{
    // look for deleted records
    foreach (Record rec in UnitOfWork.Records.ToList())
    {
        var copy = rec;
        if (!recs.Contains(rec))                      // use this one?
        if (0 == recs.Count(p => p.Id == copy.Id))    // or this one?
        {
            // if not in the new collection, remove from database
            Record deleted = UnitOfWork.Records.Single(p => p.Id == copy.Id);
            UnitOfWork.Remove(deleted);
        }
    }
    // rest of method code deleted
}
Run Code Online (Sandbox Code Playgroud)

我的问题:使用Count方法比Contains方法有速度优势(或其他优势)吗?Id属性保证是唯一的并且用于标识该特定记录,因此您不需要进行按位比较,因为我假设Contains可能会这样做.

任何人?谢谢,戴夫

Bro*_*ass 35

这会更快:

if (!recs.Any(p => p.Id == copy.Id)) 
Run Code Online (Sandbox Code Playgroud)

这有相同的优点,使用Count()-但它也停止它找到第一个匹配后不像Count()

  • 该死的......太快了! (6认同)

Joã*_*elo 13

您甚至不应该考虑,Count因为您只检查是否存在记录.你应该使用Any.

使用Countforce迭代整个枚举以获得正确的计数,Any一旦找到第一个元素就停止枚举.

至于使用Contains你需要考虑的是,对于指定的类型引用,是否等同于Id您正在执行的比较.默认情况下不是这样.


Jon*_*eet 8

假设Record实现两者GetHashCode并且Equals正确,我将完全使用不同的方法:

// I'm assuming it's appropriate to pull down all the records from the database
// to start with, as you're already doing it.
foreach (Record recordToDelete in UnitOfWork.Records.ToList().Except(recs))
{
    UnitOfWork.Remove(recordToDelete);
}
Run Code Online (Sandbox Code Playgroud)

基本上没有必要具有N*M查找时间 - 上面的代码将最终recs根据其哈希代码构建一组记录,并且比原始代码更有效地查找非匹配.

如果你真的有更多事要做,你可以使用:

HashSet<Record> recordSet = new HashSet<Record>(recs);

foreach (Record recordFromDb in UnitOfWork.Records.ToList())
{
    if (!recordSet.Contains(recordFromDb))
    {
        UnitOfWork.Remove(recordFromDb);
    }
    else
    {
        // Do other stuff
    }
}
Run Code Online (Sandbox Code Playgroud)

(我不太清楚为什么你的原始代码是Single在你已经把它作为rec...的时候从数据库中重新获取记录的.)


Mat*_*eer 6

Contains()将用于Equals()对付你的对象.如果您没有覆盖此方法,甚至可能Contains()返回不正确的结果.如果你重写它使用对象的Id确定身份,那么在这种情况下Count(),并Contains()几乎在做同样的事情.除了Contains()一旦碰到比赛就会短路,在那里Count()继续计数.Any()可能是比他们两个更好的选择.

您是否确定这是您应用中的瓶颈?感觉就像我过早优化一样.这是万恶之源,你知道:)