Which way is better for Linq Select Query or For Loop for finding something in the general list?

As far as performance is concerned, which way is better for Linq Select Query or For Loop to search for something in the general list?

+3
source share
2 answers

A few days before I tried using R&D for 50,000 records and found that it takes about 60% of the time for the loop, like the time taken by linq where is the sentence

Elapsed time for Linq: 87 ms Elapsed time for Linq: 48 ms

Elapsed time for Linq: 143 ms Elapsed time for Linq: 76 ms

etc. for more details see the code, how I did it

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;
        }

    }
}

Customer class

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; }
    }
}

As a performance, consider what I will use for Loop instead of Linq

+1

A for . , ... . (EDIT: , , ). , , . ?)

"select", . , :

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

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

, , for. , HashSet<T> .

: , . .

c:\Users\Jon\Test>test 1000000 500000 1000
FindCustomerLinq: 28531
FindCustomerListFind: 12315
FindCustomerForLoop: 9737
FindCustomerForEachLoop: 14743

, , , 1000 . , for ... , . , , 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;
    }
}
+5

Source: https://habr.com/ru/post/1719487/


All Articles