Comment soustraire une liste énorme de l'autre efficacement en C#
J'ai une très longue liste d'Id (entiers) qui représente tous les éléments qui sont actuellement dans ma base de données:
var idList = GetAllIds();
J'ai aussi un autre énorme liste générique avec les éléments à ajouter à la base de données:
List<T> itemsToAdd;
Maintenant, je voudrais supprimer tous les éléments de la liste générique dont l'Id est déjà dans le idList.
Actuellement idList est un simple tableau et je soustrais les listes comme ceci:
itemsToAdd.RemoveAll(e => idList.Contains(e.Id));
Je suis assez sûr qu'elle pourrait être beaucoup plus rapide, de sorte que les types de données dois-je utiliser pour les deux collections et quelle est la plus efficace et pratique pour soustraire eux?
Merci!
- Je voudrais savoir comment diffuser/énumérer ce ainsi, si possible...
Vous devez vous connecter pour publier un commentaire.
Transformer temporairement
idList
à unHashSet<T>
et d'utiliser la même méthode, à savoir:il devrait être beaucoup plus rapide
LINQ pourrait aider:
Votre code est lent parce que
List<T>.Contains
estO(n)
. Si votre coût total estO(itemsToAdd.Count*idList.Count)
.Vous pouvez faire idList dans un
HashSet<T>
qui aO(1)
.Contains
. Ou simplement l'utiliser Linq.Except
méthode d'extension qui le fait pour vous.Noter que
.Except
allons également supprimer tous les doublons à partir de la gauche. c'est à dire de nouveauxint[]{1,1,2}.Except(new int[]{2})
donneront lieu à{1}
et la deuxième 1 a été supprimé. Mais je suppose que ça ne pose aucun problème dans votre cas, parce que les Id sont généralement unique.itemsToAdd
. Si oui ou non c'est un problème est à l'OP (je pense que non, car ils sont déjà à l'aide deRemoveAll
leur exemple).En supposant les prémisses suivantes sont remplies:
idList
etitemsToAdd
ne peut pas contenir de doublonsvous pouvez utiliser un HashSet<T> de cette façon:
Selon la documentation de la ISet<T>.ExceptWith méthode est assez efficace:
Dans votre cas
n
est le nombre d'éléments dansidList
.idList
n'a pas à être unHashSet<int>
, il vous suffit de créer un HashSet deitemsToAdd
. Vous pourrez ensuite passeridList
àHashSet<T>.ExceptWith
comme unIEnumerable<T>
.Vous devez utiliser deux
HashSet<int>
s.Notez qu'ils sont uniques et non-ordonnées.