Frage

Hallo nehme diese 2 Methoden:

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

Welches ist schneller? Als ich bei der ersten Methode anschaue, sehe ich, dass der Speicher für Liste zugeordnet ist, was meiner Meinung nach ist es nicht erforderlich. Die IEnumerable Methode scheint mir schneller zu sein.

Zum Beispiel: Angenommen, Sie rufen

int a = GetProviderForType(myType).Count;
int b = GetProviderForType1(myType).Count();

Nun wird ein weiteres Problem ist, gibt es einen Unterschied in der Leistung zwischen diesen 2 oben?

Was denken Sie?

War es hilfreich?

Lösung

In diesem speziellen Fall des IEnumerable<T> Formular wird effizienter, da Sie nur muß die Zählung wissen. Es gibt keinen Grund, die Daten bei der Speicherung, Ändern der Größe Puffer usw., wenn Sie nicht benötigen.

Wenn Sie die Ergebnisse benötigt wieder aus irgendeinem Grund zu verwenden, würde die List<T> Form effizienter sein.

Beachten Sie, dass sowohl die Count() Erweiterung Methode und die Count Eigenschaft wird für List<T> effizient sein wie die Umsetzung der Count() überprüft, ob die Zielsequenz ICollection<T> implementiert und verwendet die Count Eigenschaft, wenn so.

Eine weitere Option, die auch sein sollte mehr effizient (wenn auch nur kurz) wäre, die Überlastung von Count zu nennen, die einen Delegierten nimmt:

private int GetProviderCount(Type type)
{
  return _objectProviders.Count(provider =>
      (provider.Key.IsAssignableFrom(type) 
       || type.IsAssignableFrom(provider.Key))
      && provider.Value.SupportsType(type));
}

Das wird die zusätzliche Ebene der Indirekt durch die Where und Select Klauseln entstehen vermeiden.

(wie Marc sagt, für kleine Datenmengen werden die Leistungsunterschiede wahrscheinlich vernachlässigbar sein sowieso.)

Andere Tipps

Die genaue Antwort wie diese Fragen können in Abhängigkeit von einer Vielzahl von Faktoren variieren, und kann weiter verändern, wie die CLR entwickelt. Der einzige Weg, um sicher zu sein, ist es zu messen, -. Und beachten Sie, dass, wenn die Differenz klein ist im Vergleich zu der Operation dies in erscheinen wird, dann sollten Sie die meisten lesbar, wartbar Art und Weise des Schreibens pick it

Und in diesem Sinne, könnten Sie auch versuchen wollen:

private IEnumerable<IObjectProvider> GetProviderForType1(Type type)
{
    return _objectProviders.Where(provider => 
                  provider.Key.IsAssignableFrom(type) ||
                  type.IsAssignableFrom(provider.Key)) &&
                  provider.Value.SupportsType(type))
                           .Select(p => p.Value);
}

Sie können sich auch eine Menge an Flexibilität geben, indem IEnumerable<T> zurückkehren und dann die ToList Extension-Methode verwenden, wenn Sie „Snapshot“ wollen die Ergebnisse in einer Liste an. Dies wird wiederholte Auswertung des Codes vermeiden, um die Liste zu generieren, wenn Sie es mehrfach untersuchen müssen.

Ein wichtiger Teil dieser Frage ist: „Wie groß ist die Daten“? Wie viele Zeilen ...

Für kleine Datenmengen, die Liste ist in Ordnung - es wird vernachlässigbare Zeit eine ausreichend große Liste zuzuordnen, und es wird nicht oft (keine, wenn Sie es sagen können, wie groß im Voraus zu sein) die Größe <. / p>

Dies ist jedoch nicht Maßstab zu riesigen Datenmengen; es scheint unwahrscheinlich, dass Ihr Provider Tausende von Schnittstellen unterstützt, so dass ich würde nicht sagen, es ist erforderlich , um dieses Modell zu gehen -. aber es wird nicht sehr groß schaden

Natürlich können Sie LINQ verwenden, auch:

return from provider in _objectProviders
       where provider.Key.IsAssignableFrom(type) ...
       select provider.Value;

Dies ist auch der latente yield Ansatz unter der Decke ...

Der wesentliche Unterschied zwischen IEnumerable und IList:

IEnumerable: Implementiert Movenext, Reset, Get Aktuelle Methoden und gibt einen Typ von IEnumerator iterieren     Durch Aufzeichnungen.

IList: Mach die IEnumerable-Schnittstelle sowie es auch eine Sammlung von nicht-generischen Objekten, die durch einen Index zugegriffen können so IEnumerable + ICollection (Manipulation von Daten) und Hinzufügen, Entfernen, Einfügen (in bestimmtem Index) sind nützlich Methoden implementiert durch IList.

Nach meiner Meinung IEnumerable auf den Code der Suche ist effizienter, aber Rückkehr Liste ist auch nützlich, wenn Sie einige Manipulation mit Daten tun wollen, und wenn Sie nur durch die Daten iterieren wollen, dann IEnumerable vorzuziehen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top