Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.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# 使用Linq Select查询或For循环搜索泛型列表中的内容,哪种方法更好?_C#_.net_Linq - Fatal编程技术网

C# 使用Linq Select查询或For循环搜索泛型列表中的内容,哪种方法更好?

C# 使用Linq Select查询或For循环搜索泛型列表中的内容,哪种方法更好?,c#,.net,linq,C#,.net,Linq,就性能而言, Linq Select Query或For Loop哪种方法在泛型列表中搜索内容更好?AFor循环可能会稍微快一点。测量它以确定。。。但再看看可读性。(编辑:当您测量它时,尝试这样做的时间要比公认答案中的基准测试的时间长。还要将这段代码所花费的时间与程序其余部分的时间进行比较。这真的是一个瓶颈吗?) 我通常不会使用“select”,除非您实际需要投影一系列结果。要查找单个元素,请使用: list.Find(x => x.Name == "Foo"); 或 我相信这两种方法都

就性能而言,
Linq Select Query或For Loop哪种方法在泛型列表中搜索内容更好?

A
For
循环可能会稍微快一点。测量它以确定。。。但再看看可读性。(编辑:当您测量它时,尝试这样做的时间要比公认答案中的基准测试的时间长。还要将这段代码所花费的时间与程序其余部分的时间进行比较。这真的是一个瓶颈吗?)

我通常不会使用“select”,除非您实际需要投影一系列结果。要查找单个元素,请使用:

list.Find(x => x.Name == "Foo");

我相信这两种方法都比相应的
for
循环更具可读性。如果您只是在寻找一个对象,那么您可能需要考虑使用<代码> HasStuts<代码>,或者与列表结合使用。

编辑:这里有一个测试基准。代码在结果下面

c:\Users\Jon\Test>test 1000000 500000 1000
FindCustomerLinq: 28531
FindCustomerListFind: 12315
FindCustomerForLoop: 9737
FindCustomerForEachLoop: 14743
这是在一个包含一百万个元素的列表中,找到了一半,但做了1000次。所以是的,for循环的
速度实际上是原来的三倍。。。但在这种差异变得显著之前,你必须做很多。如果你经常做这类事情,你应该寻找其他的选择,比如
字典

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;
    }
}
使用系统;
使用System.Collections.Generic;
使用系统诊断;
使用System.Linq;
公共类客户
{
公共int ID{get;set;}
公共字符串名称{get;set;}
公共字符串地址{get;set;}
公用字符串电话{get;set;}
}
课堂测试
{
静态void Main(字符串[]参数)
{
int size=int.Parse(args[0]);
int id=int.Parse(args[1]);
int迭代=int.Parse(args[2]);
var列表=新列表(大小);
对于(int i=0;ic.ID==ID);
}
静态客户FindCustomerListFind(列出客户,int id)
{
返回customers.Find(c=>c.ID==ID);
}
静态客户FindCustomerForLoop(列出客户,int id)
{
for(int i=0;i
几天前,我对50000条记录进行了与研发相同的尝试,结果发现 for循环所花费的时间约为linq where子句所花费时间的60%

Linq的运行时间:87毫秒 Linq的运行时间:48毫秒

Linq的运行时间:143毫秒 Linq的运行时间:76毫秒

等等。。有关详细信息,请参阅代码我是如何做到的

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;

namespace SearchingList
{
    public partial class Form1 : Form
    {
        private int searchingID = 0;
        public int SearchingID 
        {
            get
            {       
                if (string.IsNullOrEmpty(txtID.Text))
                    searchingID = 0;
                else
                    int.TryParse(txtID.Text, out searchingID);
                return searchingID;
            }
            set
            {
                SearchingID = searchingID;
            }
        }
        public Form1()
        {
            InitializeComponent();
        }

        private void btnsearch_Click(object sender, EventArgs e)
        {
            List<Customer> lstcustomersFound = new List<Customer>();
            Stopwatch stp = new Stopwatch();
            stp.Start();
            lstcustomersFound = GetSearchedCustomersByLinq(SearchingID, (List<Customer>)dgvAllData.DataSource);
            stp.Stop();
            lblLinq.Text = "Elapsed Time Linq : " + stp.ElapsedMilliseconds.ToString() + " ms";
            stp.Start();
            lstcustomersFound = GetSearchedCustomersByForLoop(SearchingID, (List<Customer>)dgvAllData.DataSource);
            stp.Stop();
            lblFor.Text ="Elapsed Time for loop : " + stp.ElapsedMilliseconds.ToString() + " ms";
            dgvSearched.DataSource = lstcustomersFound;
        }

        private List<Customer> GetSearchedCustomersByForLoop(int searchingID, List<Customer> lstcustomers)
        {
            List<Customer> lstcustomersFound = new List<Customer>();
            foreach (Customer customer in lstcustomers)
            {
                if (customer.CusomerID.ToString().Contains(searchingID.ToString()))
                {
                    lstcustomersFound.Add(customer);
                }
            }
            return lstcustomersFound;
        }

        private List<Customer> GetSearchedCustomersByLinq(int searchingID, List<Customer> lstcustomers)
        {
            var query = from customer in lstcustomers
                        where customer.CusomerID.ToString().Contains(searchingID.ToString())
                        select customer as Customer;
            return query.ToList();
        }


        private void Form1_Load(object sender, EventArgs e)
        {
            List<Customer> customers = new List<Customer>();
            Customer customer;
            for (int id = 1; id <= 50000; id++)
            {
                customer = new Customer();
                customer.CusomerAddress = "Address " + id.ToString();
                customer.CusomerID = id;
                customer.CusomerName = "Cusomer Name " + id.ToString(); 
                customer.CusomerPhone= "Phone " + id.ToString();
                customers.Add(customer);
            }
            dgvAllData.DataSource = customers;
        }

    }
}

由于性能是考虑因素,我将选择for Loop而不是Linq

查看搜索“Linq performance”时通常会遇到的无数问题。这是复制列表,而不是查找特定条目。我还认为,你们测量的时间太短,这些结果没有意义。你的情况也很可疑-寻找“10”会找到“100”例如。。。为什么在循环的每次迭代中都要将searchingID转换为字符串?我知道你在这两种情况下都在做同样的事情,但即使如此,我也不会把它作为一个好的基准。我可能遗漏了一些东西,但你不需要在某个地方重置秒表吗?我又创建了一个程序,没有发布在这里,其中customerId是一个字符串,可以根据customerId文本框中更改的文本填充搜索结果。性能结果几乎相同
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;

namespace SearchingList
{
    public partial class Form1 : Form
    {
        private int searchingID = 0;
        public int SearchingID 
        {
            get
            {       
                if (string.IsNullOrEmpty(txtID.Text))
                    searchingID = 0;
                else
                    int.TryParse(txtID.Text, out searchingID);
                return searchingID;
            }
            set
            {
                SearchingID = searchingID;
            }
        }
        public Form1()
        {
            InitializeComponent();
        }

        private void btnsearch_Click(object sender, EventArgs e)
        {
            List<Customer> lstcustomersFound = new List<Customer>();
            Stopwatch stp = new Stopwatch();
            stp.Start();
            lstcustomersFound = GetSearchedCustomersByLinq(SearchingID, (List<Customer>)dgvAllData.DataSource);
            stp.Stop();
            lblLinq.Text = "Elapsed Time Linq : " + stp.ElapsedMilliseconds.ToString() + " ms";
            stp.Start();
            lstcustomersFound = GetSearchedCustomersByForLoop(SearchingID, (List<Customer>)dgvAllData.DataSource);
            stp.Stop();
            lblFor.Text ="Elapsed Time for loop : " + stp.ElapsedMilliseconds.ToString() + " ms";
            dgvSearched.DataSource = lstcustomersFound;
        }

        private List<Customer> GetSearchedCustomersByForLoop(int searchingID, List<Customer> lstcustomers)
        {
            List<Customer> lstcustomersFound = new List<Customer>();
            foreach (Customer customer in lstcustomers)
            {
                if (customer.CusomerID.ToString().Contains(searchingID.ToString()))
                {
                    lstcustomersFound.Add(customer);
                }
            }
            return lstcustomersFound;
        }

        private List<Customer> GetSearchedCustomersByLinq(int searchingID, List<Customer> lstcustomers)
        {
            var query = from customer in lstcustomers
                        where customer.CusomerID.ToString().Contains(searchingID.ToString())
                        select customer as Customer;
            return query.ToList();
        }


        private void Form1_Load(object sender, EventArgs e)
        {
            List<Customer> customers = new List<Customer>();
            Customer customer;
            for (int id = 1; id <= 50000; id++)
            {
                customer = new Customer();
                customer.CusomerAddress = "Address " + id.ToString();
                customer.CusomerID = id;
                customer.CusomerName = "Cusomer Name " + id.ToString(); 
                customer.CusomerPhone= "Phone " + id.ToString();
                customers.Add(customer);
            }
            dgvAllData.DataSource = customers;
        }

    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SearchingList
{
    public class Customer
    {
        public int CusomerID { get; set; }
        public string CusomerName { get; set; }
        public string CusomerAddress { get; set; }
        public string CusomerPhone { get; set; }
    }
}