En ce qui concerne les performances, Quelle est la meilleure solution Linq Select Query ou For Loop pour rechercher quelque chose dans la liste générique?Quelle est la meilleure solution Linq Select Query ou For Loop pour rechercher quelque chose dans la liste générique?
Répondre
Quelques jours avant d'essayer même chose que R & D pour 50000 enregistrements et a constaté que boucle for prend environ 60% de temps que le temps pris par LINQ clause where
temps écoulé pour Linq: 87 ms temps écoulé pour Linq: 48 ms
temps écoulé pour Linq: 143 ms temps écoulé pour Linq: 76 ms
et ainsi de suite .. pour plus de détails voir le code comment je l'ai fait
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;
}
}
}
Classe client
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; }
}
}
que la performance est considération que je vais aller au lieu de boucle For Linq
C'est * copier * une liste plutôt que de trouver une entrée spécifique. Je dirais aussi que vous mesurez pour * way * trop peu de temps pour que ces résultats soient significatifs. Votre condition est également très suspecte - la recherche de "10" va trouver "100" par exemple ...et pourquoi convertir le searchID en une chaîne à chaque itération dans la boucle? Je sais que vous faites la même chose dans les deux cas, mais même ainsi je ne l'utiliserais pas comme un bon point de référence. –
Il me manque probablement quelque chose, mais vous ne devez pas réinitialiser ce chronomètre quelque part? – Svish
Je voudrais aussi dire que je suis d'accord avec Jon Skeet ... – Svish
Une boucle for
peut très bien être très légèrement plus rapidement. Mesurez-le pour en être sûr ... mais regardez la lisibilité. (EDIT: Lorsque vous le mesurez, essayez de le faire pendant plus longtemps que le benchmark dans la réponse acceptée, comparez également le temps pris pour ce morceau de code avec le temps pour le reste de votre programme.) Est-ce vraiment un goulot d'étranglement?
Je n'utiliserais généralement pas de "select", sauf si vous avez réellement besoin de projeter une séquence de résultats. Pour trouver un seul élément, utilisez:
list.Find(x => x.Name == "Foo");
ou
list.FirstOrDefault(x => x.Name == "Foo");
je crois que les deux sont beaucoup plus lisible que la boucle for
correspondante. Si vous cherchez simplement un objet alors vous pourriez envisager d'utiliser un HashSet<T>
à la place ou en combinaison avec la liste.
EDIT: Voici un point de référence pour le tester. Le code est en dessous des résultats.
c:\Users\Jon\Test>test 1000000 500000 1000
FindCustomerLinq: 28531
FindCustomerListFind: 12315
FindCustomerForLoop: 9737
FindCustomerForEachLoop: 14743
Alors que cherche dans une liste de millions éléments, trouver un à mi-chemin, mais le faire fois. Alors oui, la boucle for
est en fait trois fois plus rapide ... mais vous devrez faire un horrible beaucoup beaucoup avant que cette différence réelle devienne significative. Si vous faites ce genre de chose, vous devriez chercher d'autres options comme 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;
}
}
- 1. Jointure externe ou requête dynamique, quelle est la meilleure solution?
- 2. Quelle est la meilleure explication pour le terme "générique"?
- 3. Rechercher un objet dans la liste générique
- 4. "for loop" pour ValueCollection
- 5. Quelle est la meilleure solution MemCache pour les applications ASP.NET?
- 6. Quelle est la meilleure pratique pour sortir une variable qui peut contenir ou non quelque chose en PHP?
- 7. interface générique: liste de quelque chose de spécifique
- 8. Quelle est la meilleure façon de stocker des messages texte? Quelque chose comme SMS
- 9. Quelle est la meilleure façon de faire quelque chose périodiquement à Erlang?
- 10. Quelle est la meilleure solution pour migrer des tables Linq DBML?
- 11. Quelle est la meilleure façon de montrer à l'utilisateur que quelque chose se charge sur l'iPhone?
- 12. Quelle est la meilleure: DMG ou PackageMaker
- 13. Quelle est la différence entre déclarer comme nouveau et comme quelque chose = quelque chose de nouveau dans vb.net?
- 14. Est-ce que cela fonctionnerait pour rechercher quelque chose dans ma base de données?
- 15. Linq: Quelle est la différence entre Select et Où
- 16. Quelque chose de mieux que .ToArray() pour forcer l'énumération de la sortie LINQ
- 17. Boucle via la liste générique dans vb.net
- 18. Quelle est la meilleure façon d'optimiser ou de "régler" les expressions LINQ?
- 19. Vérifier si mysql_query a retourné quelque chose ou non
- 20. yahoo-pipes ou plugin ou quelque chose ...
- 21. Quelle est la meilleure pratique pour définir un service de savon (opération générique vs opération spécifique)?
- 22. SQL Max (quelque chose, 0) solution de type
- 23. LINQ Query ou une procédure stockée pour retourner la valeur maximale indiquée dans une colonne
- 24. Quel est le meilleur: require_once? ou if (! defined ('FOOBAR')) exigent? ou quelque chose d'entièrement différent?
- 25. Quelle est la meilleure solution pour le regroupement de connexions de bases de données en python?
- 26. Quelle est la solution optimale pour l'appariement de mots-clés?
- 27. Quelle est la meilleure façon d'analyser un flux dans une structure ou une classe?
- 28. Quelle est la différence entre while (true) et loop?
- 29. Quelle est la meilleure solution de référencement pour connecter en profondeur une application/un site flex?
- 30. Quelle est la meilleure solution de serveur DNS pour Windows Server 2008 Web Edition
Voir http://stackoverflow.com/questions/ 1044236 –
Et en général l'une des nombreuses questions que vous trouverez si vous recherchez "performance linq". –