C#在List中查找元素

时间:2016-11-08 17:12:44

标签: c# list lambda

我们说我有以下C#代码

bool c1 = my_list.Contains(sentence);
bool c2 = my_list.Any(s => s == sentence);

执行以下任一操作之间有什么区别吗?

DECLARE @cols AS NVARCHAR(MAX),
@query  AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME(LineSubType) 
                from TrnsSalaryProcessRegisterDetail 
                GROUP By QUOTENAME(LineSubType)
                ORDER BY QUOTENAME(LineSubType)
                --inner join TrnsSalaryProcessRegister on TrnsSalaryProcessRegisterDetail.SRID=TrnsSalaryProcessRegister.Id
                --where TrnsSalaryProcessRegisterDetail.LineValue!=null
        FOR XML PATH(''), TYPE
        ).value('.', 'NVARCHAR(MAX)') 
    ,1,1,'')
set @query = '
     select a.empid,a.payrollname,a.DepartmentName,s.PeriodName,
        d.*
     from TrnsSalaryProcessRegister s
     inner join mstemployee a on a.id=s.empid
     inner join 
     (
        SELECT SRID,' + @cols + ' 
        from 
        (
            select SRID,LineSubType, LineValue
            from TrnsSalaryProcessRegisterDetail

        ) x
        pivot 
        (
            sum(LineValue)
            for LineSubType in (' + @cols + ')
        ) p 
      ) d
        on s.ID = d.SRID where s.PeriodName=''FY2017-Sep'' and a.payrollname=''EmcoStaff'' order by a.empid asc'
        --print(@query)

        execute(@query);

我认为背后的纯算法并不完全相同。但是我身边的实际差异是什么?比另一种更快或更有效吗?一种方法有时会返回true而另一种方法是假的吗?我应该考虑选择一种方法还是另一种方法?或者它完全取决于我,并且在任何情况下都可以工作?

3 个答案:

答案 0 :(得分:2)

实际上,这两者将以几乎相同的方式运作:迭代列表的项目并检查句子是否与任何列表元素匹配,给出了大约O(n)的复杂性。我会争辩List.Contains,因为这更容易,更自然,但它完全是优惠的!

现在,如果您在查找复杂性和速度方面寻找更快的东西,我建议HashSet<T>。 HashSets一般来说,查找大约O(1),因为理论上,哈希函数应该是一个恒定时间操作。再次,只是一个建议:)

答案 1 :(得分:2)

最受欢迎的答案并不完全正确(而且这是一个很大的原因并不总是有效的原因)。在这种情况下,任何都比包含慢(大约两倍)。

任何每次迭代都会有一个额外的调用,你在列表中的每个项目上指定的委托,包含的内容不一定要做。额外的通话会大大减慢它的速度。

结果会一样,但速度会有很大不同。

示例基准:

Stopwatch watch = new Stopwatch();

List<string> stringList = new List<string>();

for (int i = 0; i < 10000000; i++)
{
    stringList.Add(i.ToString());
}
int t = 0;
watch.Start();
for (int i = 0; i < 1000000; i++)
    if (stringList.Any(x => x == "29"))
        t = i;

watch.Stop();
("Any takes: " + watch.ElapsedMilliseconds).Dump();
GC.Collect();
watch.Restart();

for (int i = 0; i < 1000000; i++)
    if (stringList.Contains("29"))
        t = i;

watch.Stop();

("Contains takes: " + watch.ElapsedMilliseconds).Dump();

结果:

Any takes: 481
Contains takes: 235

迭代的大小和数量不会影响%差异,任何总是会慢一些。

答案 2 :(得分:1)

对于string个对象,没有区别,因为== operator只是调用String.Equals

但是,对于其他对象,==.Equals之间可能存在差异 - 查看implementation of .Contains,它会使用EqualityComparer<T>.Default,它会挂钩Equals(T) 1}}只要您的类实现IEquatable<T>(其中T本身)。在不重载==的情况下,大多数类使用引用比较==,因为这是他们从Object继承的内容。