Comment optimiser ce code?
Parentdoglist, Childdoglistis - Ilist. Doglistbox - Boîte de liste p> EDIT: strong>
Parentdogtypelist, chiltypelist a été renommé parentdoglist, enfantdoglist, où les deux ne sont pas liés les uns avec les autres p> a été modifié en p> Histoire complète: strong> p> J'ai besoin de peupler une baisse qui réduirait une relation d'enfant parent. Il y a certains chiens qui peuvent ne pas avoir d'enfant et qui seraient appelés comme unafdog. Et j'ai aussi besoin de montrer le nombre de chiens dans cette catégorie particulière p> DD ressemblerait à p> donc, la parentdogliste apporterait tout l'enfant et Les éléments de feuilles avec le comte et la chouddoglist auraient le parent et la feuille d'identité d'où je serais en mesure de peupler l'enfant respectif à leur parent et de lier la feuille directement. P> Le chien des parents, de l'enfant et de la feuille serait Maintenir dans une table et différencié par StatutId et Count serait dans une autre table. P> aucun parent n'aurait aucun compte, seul enfant et feuille n'aurait compter que P> p> p>
7 Réponses :
Vous pouvez trier Mais vous pouvez trier les conteneurs dans Ensuite, si vous exécutez ce code parentdoglist code> et
enfantdoglist code> et faire linéaire
O (n) code> Recherche d'algorithme Insead de ce
O (n ^ 2 ) code>. p>
O ((parentdoglist.size () + enfantdoglist.size ()) * log2 (parentdoglist.size () + enfantdoglist.Size ())) code>. < / p>
O (journal (n)) code> temps. P>
foreach (var ParentDog in ParentDoglist.Where(p=>ChildDoglist.Any(c=>c.Key== p.Key)).ToList()) dogListBox.Items.Add(new ListItem(ParentDog.Name, ParentDog.Key)); That's how you would do it with LinQ
Cela n'a-t-il pas encore une boucle imbriquée implicite?
C'est toujours O (n ^ 2) ;-( uniquement avec des vêtements de paresseux dans le conteneur de childdoglist sans aucune optimisation.
Votre plus gros problème est probablement le Pour rendre la boucle interne beaucoup plus petite, vous pouvez créer une recherche pour les touches de la boucle interne. P> doglistbox.items.add code>. Ajout de chaque élément à un moment est assez coûteux.
listbox.items.addrange code>
est plus efficace. List<ListItem> listItems = new List<ListItem>();
ILookup<string, Dog> childDogsPerKey = ChildDoglist.ToLookup(dog => dog.Key);
foreach (Dog ParentDog in ParentDoglist)
{
foreach (Dog ChildDog in childDogsPerKey[ParentDog.Key])
{
listItems.Add(new ListItem(ParentDog.Name, ParentDog.Key));
}
}
dogListBox.Items.AddRange(listItems.ToArray());
D'accord que Addrange aidera probablement beaucoup.
Étant donné que cela vient de la DB, les voyages de la base de données sont susceptibles d'être un tueur de performance. Aussi la comparaison Redesignez cela pour que vous puissiez Sélectionne unique pour saisir toutes les données dans une requête. P> ALBIN mentionné Addrange, mais vous pouvez même prendre cela une étape plus loin et virtualiser votre grille afin qu'il ne tire que les rangées affichées à l'utilisateur lorsqu'elle examine cette partie de la grille. p> Pour générer votre liste Il apparaît que vous devez renvoyer quelque chose comme celui-ci à partir de la DB: P> parentdog.key == enfantdog.key code> peut être effectuée dans SQL, de sorte que vous ne tirez pas toutes ces données à votre application pour le jeter.
Parent1, null, null
Parent1, Child1, 110
Parent1, Child12, 12
Parent2, null, null
Parent2, Child21, 23
Parent2, Child22 ,20
Leaf1, null, 20
Leaf2, null, 34
Modifier ma question pour expliquer le scénario complet
Oui, mais comment remplir la boîte de liste sans boucle?
@SRI, une seule requête et une seule boucle, je ne peux plus m'empêcher de schéma de table et de saveur SQL que vous utilisez (supposant SQL Server)
Mis à jour avec le schéma que j'utilise mysql
J'ai utilisé deux requêtes qui vont chercher le compte pour la feuille et l'enfant. L'autre est utilisé pour obtenir les catégories qui aideraient à trouver quel enfant tombe sous quel parent!
Ce n'est pas le forach qui est lent, il ajoute et rendant de nouveaux articles.
Ajouter BeginUpdate / endupdate: p>
dogListBox.BeginUpdate(); foreach (Dog ParentDog in ParentDoglist) { foreach (Dog ChildDog in ChildDoglist) { if(ParentDog.Key==ChildDog.Key) dogListBox.Items.Add(new ListItem(ParentDog.Name, ParentDog.Key)); } } dogListBox.EndUpdate();
Je pense toujours que la manière la plus élégante et optimisée est d'utiliser Linq pour cela.
box.Items.AddRange( ParentDoglist.Join(ChildDoglist, p => p.StatusID, c => c.StatusID, (p,c)=>p) .Select(r=>new ListItem(r.StatusID, r.Name)).ToArray());
Vous pouvez remplacer la boucle de forach imbriquée avec une simple expression linq. Pour que cela fonctionne, vous devez utiliser System.Linq;
Dogtypelist est-il une liste de tous types de chiens et parentdogtypelist un sous-ensemble de types de chiens?
Ces listes sont-elles provenant d'une base de données?
@Sam Safran Ouais les deux listes proviennent de dB.
@Preeet Sangha j'ai plus de 3 forestières intérieures du même genre, donc j'ai pensé à réduire la forise
@Sri, pouvez-vous modifier la question inclure votre schéma de base de données pour les tables ici. une requête directe sera probablement la plus rapide
Vérifier: Si un chien a plus d'un enfant, vous le souhaitez dans la liste de liste plusieurs fois? Votre code semble faire une jointure extérieure.
@Henk Holterman a édité ma question pour expliquer le scénario complet