C# List<T> vs IEnumerable<T> question de la performance
Hi supposons que ces 2 méthodes:
private List<IObjectProvider> GetProviderForType(Type type)
{
List<IObjectProvider> returnValue = new List<IObjectProvider>();
foreach (KeyValuePair<Type, IObjectProvider> provider in _objectProviders)
{
if ((provider.Key.IsAssignableFrom(type) ||
type.IsAssignableFrom(provider.Key)) &&
provider.Value.SupportsType(type))
{
returnValue.Add(provider.Value);
}
}
return returnValue;
}
private IEnumerable<IObjectProvider> GetProviderForType1(Type type)
{
foreach (KeyValuePair<Type, IObjectProvider> provider in _objectProviders)
if ((provider.Key.IsAssignableFrom(type) ||
type.IsAssignableFrom(provider.Key)) &&
provider.Value.SupportsType(type))
yield return provider.Value;
}
Lequel est le plus rapide? Quand je regarde la première méthode, je vois que la mémoire est allouée pour la Liste, ce qui à mon avis il n'est pas nécessaire. Le IEnumerable méthode semble être plus rapide pour moi.
Par exemple, supposons que vous appelez
int a = GetProviderForType(myType).Count;
int b = GetProviderForType1(myType).Count();
Maintenant, une autre question est, est-il une différence de performance entre ces 2 ci-dessus?
Qu'en pensez-vous?
La réponse à tout "qui est le plus rapide?" questions est la même: Essayez les deux méthodes. Sortir d'un chronomètre. Alors vous saurez.
OriginalL'auteur PaN1C_Showt1Me | 2009-07-31
Vous devez vous connecter pour publier un commentaire.
Dans ce cas particulier, à l'aide de la
IEnumerable<T>
formulaire sera plus efficace, car vous seulement besoin de connaître le nombre. Il n'y a aucun point dans le stockage de données, le redimensionnement de tampons, etc si vous n'avez pas besoin d'.Si vous avez besoin d'utiliser les résultats de nouveau pour une raison quelconque, le
List<T>
forme serait plus efficace.Il est à noter que la
Count()
méthode d'extension et de l'Count
propriété sera efficace pourList<T>
que la mise en œuvre deCount()
vérifie pour voir si la séquence cible implémenteICollection<T>
et utilise leCount
bien si.Une autre option qui devrait être encore plus efficace (si seulement) serait d'appeler la surcharge de
Count
qui prend un délégué:Qui permettra d'éviter le niveau supplémentaire de indirections engagés par le
Where
etSelect
clauses.(Comme Marc dit, pour les petites quantités de données, les différences de rendement sera probablement négligeable de toute façon.)
Doh - bien sûr. Corrigé, merci 🙂
Toutes vos réponses m'ont vraiment aidé, mais je pense que celui-ci a tout ce qui est mentionné, donc je l'accepte. Merci!!!!
OriginalL'auteur Jon Skeet
La réponse précise à des questions de ce genre peuvent varier en fonction de beaucoup de facteurs, et peut changer en outre que la CLR évolue. La seule façon d'en être sûr est de mesurer et de garder à l'esprit que si la différence est faible par rapport à l'opération, celle-ci apparaîtra, alors vous devez choisir le plus lisible, maintenable façon de l'écrire.
Et sur cette note, vous pouvez également essayer:
Vous pouvez également vous donner beaucoup de souplesse en retournant
IEnumerable<T>
et puis, à l'aide de laToList
méthode d'extension si vous voulez "instantané" les résultats dans une liste. Cela permettra d'éviter la répétition de l'évaluation du code pour générer la liste, si vous avez besoin d'examiner de multiples reprises.OriginalL'auteur Daniel Earwicker
Une partie importante de cette question est "quelle est la taille des données"? Combien de lignes...
Pour de petites quantités de données, la liste est très bien - il faudra négligeable de temps à consacrer une assez grande liste, et il n'est pas redimensionné à de nombreuses reprises (aucun, si vous pouvez vous le dire combien de gros pour être à l'avance).
Cependant, ce n'est pas adaptée à l'échelle d'énormes volumes de données; il semble peu probable que votre fournisseur prend en charge des milliers d'interfaces, donc je ne dirais pas que c'est nécessaire pour aller à ce modèle, mais il ne fera pas de mal extrêmement.
Bien sûr, vous pouvez utiliser LINQ, trop:
C'est également le report de la
yield
approche sous les couvertures...OriginalL'auteur Marc Gravell
La Principale Différence Entre IEnumerable et IList:
IEnumerable:
Implémente la méthode MoveNext,Reset,Obtenir des Méthodes Actuelles et Renvoie un Type de IEnumerator pour Itérer
Par Le Biais D'Enregistrements.
IList : Expose l'Interface IEnumerable ainsi que c'est aussi une collection de non-générique des objets qui peuvent accéder par le biais de l'index pour IEnumerable+ICollection(Manipulation de données) et d'ajouter,supprimer,Insérer(à Index spécifique) sont utiles méthodes mises en œuvre par IList.
Après avoir regardé votre Code À Mon Avis IEnumerable est plus efficace mais le retour liste est également utile si vous voulez faire un peu de manipulation de données et si vous voulez juste pour Itérer sur les données, puis IEnumerable est préférable.
Une autre possibilité serait de revenir à un type qui implémente
ICollection
(non générique!) en lecture seule de la mode ainsi queIEnumerable<T>
et, éventuellement,ICollection<T>
. Si une classe qui implémenteIEnumerable<T>
met également en œuvreICollection
ouICollection<T>
, leCount
méthode d'extension pourIEnumerable<T>
utilisera leCount
méthode de l'une de ces interfaces. Sinon, il faudra d'énumérer tous les éléments pour obtenir un nombre. Notez que la non-forme générique est un peu plus utile à cette fin parce que......un
IEnumeration<Cat>
peut être utilisé comme unIEnumeration<Animal>
, mais unICollection<Cat>
ne peut pas être utilisé comme unICollection<Animal>
. Si une routine qui s'attend à uneIEnumeration<Animal>
ont reçu une instance de la classe qui implémenteICollection<Cat>
mais non pas le non-génériqueICollection
, elle n'aurait aucun moyen de savoir que la collection doit être jeté àICollection<Cat>
pour obtenir le nombre. Si la classe implémente non génériqueICollection
, toutefois, le code qui s'attend à uneIEnumerable<Animal>
aurait aucune difficulté à en trouver.OriginalL'auteur Vishal Patwardhan