哪种方式更好的Linq Select Query或For Loop来搜索通用List中的内容?

3 .net c# linq

就性能而言,哪种方式更好的Linq Select Query或For Loop来搜索通用List中的东西?

Jon*_*eet 5

一个for循环可能会非常快一些.测量它以确定...但然后看看可读性.(编辑:当你测量它时,尝试这样做比在接受的答案中的基准时间更长.也比较这段代码所花费的时间和你的其他程序的时间.这真的是一个瓶颈吗?)

我通常不会使用"选择",除非你实际上需要投射一系列结果.要查找单个元素,请使用:

list.Find(x => x.Name == "Foo");
Run Code Online (Sandbox Code Playgroud)

要么

list.FirstOrDefault(x => x.Name == "Foo");
Run Code Online (Sandbox Code Playgroud)

我相信这两个都比相应的for循环更可读.如果您只是在寻找一个对象,那么您可能需要考虑使用HashSet<T>替代或与列表组合使用.

编辑:这是测试它的基准.代码低于结果.

c:\Users\Jon\Test>test 1000000 500000 1000
FindCustomerLinq: 28531
FindCustomerListFind: 12315
FindCustomerForLoop: 9737
FindCustomerForEachLoop: 14743
Run Code Online (Sandbox Code Playgroud)

因此,我们会查看一百万个元素的列表,找到它的一半,但这样做1000次.所以,是的,在for循环实际上是三倍快...但你必须做这样的一个可怕的很多前这种差异实际变得显著.如果你做的那么多,你应该寻找其他选择,如a Dictionary.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

public class Customer
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }
    public string Phone { get; set; }
}

class Test
{
    static void Main(string[] args)
    {
        int size = int.Parse(args[0]);
        int id = int.Parse(args[1]);
        int iterations = int.Parse(args[2]);

        var list = new List<Customer>(size);
        for (int i=0; i < size; i++)
        {
            list.Add(new Customer {
                ID = i, 
                Address = "Address " + i,
                Name = "Cusomer Name " + i,
                Phone= "Phone " + i,
            });
        }

        Time(FindCustomerLinq, list, id, iterations);
        Time(FindCustomerListFind, list, id, iterations);
        Time(FindCustomerForLoop, list, id, iterations);
        Time(FindCustomerForEachLoop, list, id, iterations);
    }

    static void Time(Func<List<Customer>, int, Customer> action,
                     List<Customer> list,
                     int id, int iterations)
    {
        Stopwatch sw = Stopwatch.StartNew();
        for (int i=0; i < iterations; i++)
        {
            action(list, id);
        }
        sw.Stop();
        Console.WriteLine("{0}: {1}", action.Method.Name, (int) sw.ElapsedMilliseconds);
    }

    static Customer FindCustomerLinq(List<Customer> customers, int id)
    {
        return customers.FirstOrDefault(c => c.ID == id);
    }

    static Customer FindCustomerListFind(List<Customer> customers, int id)
    {
        return customers.Find(c => c.ID == id);
    }

    static Customer FindCustomerForLoop(List<Customer> customers, int id)        
    {
        for (int i=0; i < customers.Count; i++)
        {
            if (customers[i].ID == id)
            {
                return customers[i];
            }
        }
        return null;
    }

    static Customer FindCustomerForEachLoop(List<Customer> customers, int id)
    {
        foreach (Customer c in customers)
        {
            if (c.ID == id)
            {
                return c;
            }
        }
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)