2009-04-13 14 views
3

Ich weiß nicht, ob der Titel Sinn macht, aber im Grunde frage ich mich die Meinungen der Leute, ob öffentliche Mitglieder zu berechnen, wann immer sie geändert werden müssen, oder sobald sie zugegriffen werden ?Up-to-date vs On-Demand

Angenommen, Sie haben eine Klasse wie CustomCollection, die eine Eigenschaft namens Count hat. Sollte Count für jede Add, Remove, etc. Operationen aktualisiert werden, oder sollte es nur zum Zeitpunkt des Zugriffs berechnet werden?

Keeping up-to-date scheint intuitiv, aber dann fragt man sich, wie oft Menschen Add nennen, Remove, etc vs .Count.

Gibt es auch eine Hybrid-Version, in der Sie es beim Zugriff auf die Eigenschaft zwischenspeichern können? Ich denke, dass eine andere Variable aktualisiert werden müsste, oder?

Antwort

4

Die meisten Informationen über den -Status der Klasse sollten immer als Nebeneffekt der Manipulation der Daten auf dem neuesten Stand sein. Zum Beispiel basiert die Count-Eigenschaft auf dem internen Speicher der Daten (dh der Array-Länge).

Andere Eigenschaften, die von bestimmten Bedingungen des Klassenstatus abhängen, müssen möglicherweise berechnet werden. Zum Beispiel könnte eine ContainsValidOrder Eigenschaft von Aufträgen in der Klasse abhängen. Für diese Eigenschaften müssen Sie die Verwendung der Klasse auswerten und entscheiden, ob die Kosten für die Berechnung des Werts beim Hinzufügen und Entfernen von Elementen aus der Sammlung günstiger sind, als bei jedem Zugriff auf die Eigenschaft die gesamte Sammlung zu scannen.

Die .NET-Richtlinien legen jedoch nahe, dass Eigenschaften keinen komplexen Code ausführen und dass der wiederholte Zugriff auf die Eigenschaft keine Nebenwirkungen oder Auswirkungen auf die Leistung hat. Daher kann es für Eigenschaften, die berechnete Daten darstellen, besser sein, eine Methode GetXXX zu verwenden. Dies zeigt dem Entwickler, der Ihre Bibliothek verwendet, an, dass 1. die Berechnung einige Zeit dauern kann und 2. sie den Wert für die Dauer ihrer Aufgabe beibehalten sollten.

1

Diese Antwort hängt von der Art der Anwendung ab. Und die spezifische Situation.

Für eine Zählvariable würde ich sie normalerweise im laufenden Betrieb aktualisieren, da die zu berechnenden Kosten unerschwinglich sind und die zu speichernden Kosten sehr niedrig sind.

Unter anderen Umständen die Kosten sehr gering caluculate auch sein mag, aber die Kosten für die Lagerung könnte hoch sein (es vielleicht in Bezug auf die Anzahl der Plätze Code müssen beibehalten würde zu fehlerfrei halten)

4

Sie Richtig, wenn du sagst, du musst überlegen, wie oft auf diese Funktionen zugegriffen wird. Wenn auf count die ganze Zeit zugegriffen wird, sollte es nicht on-demand sein, da dies langsamer als notwendig wäre. Wenn auf die anderen Funktionen mehr zugegriffen wird, wäre die erneute Berechnung von count jedes Mal ebenfalls eine Verschwendung.

Ein mittlerer Grund wäre etwas, das count bei Bedarf berechnet, wenn ein Flag auf false gesetzt ist, und setzt dann das Flag auf wahr. Anrufe an add, remove usw. würden das Flag auf false setzen.

Etwas wie folgt aus:

Class CachedCount 
    int count = 0; 
    boolean count_is_valid = false; 

    int getCount() 
     if count_is_valid 
      return count; 
     else 
      count = calculate_count(); 
      count_is_valid = true; 
      return count; 

    void Add(item) 
     count_is_valid = false; 
     ... 

    ... 

Beachten Sie, dass dies wirklich nur einen Vorteil bieten würden, wenn Sie count mehrmals in einer Reihe zuzugreifen, ohne add Zugriff remove usw. dazwischen, und dass die Zugriffe auf add, remove usw. werden nicht mit Aufrufen von count verschachtelt. Der Vorteil davon ist verloren, wenn die Anforderungen interleaved sind. Der größte Vorteil kommt von Sequenzen wie: add, add, add, remove, remove, add, count, count, count, count, count, count anstatt add, count, add, count, remove, count, remove, count, add, count.

+0

Danke Welbog, kannst du bitte ein kleines Beispiel für deinen Mittelweg geben? –

+0

Schneller als ich :) –

+0

Da ist es in Pseudocode. Ich überlasse es als Übung, es in C# umzuwandeln. Oder irgendetwas anderes. – Welbog

1

Möglicherweise möchten Sie eine Art von Messwerten dazu erstellen, wie häufig auf diese öffentlichen Mitglieder zugegriffen wird, im Gegensatz zu der Zeit, die für die Berechnung dieser öffentlichen Mitglieder benötigt wird. Wenn es eine triviale Operation ist, um sie auf dem neuesten Stand zu halten, dann tun Sie es auf intuitivere Weise, wenn es ein kompliziertes Verfahren zum Aktualisieren ist, aber selten zugegriffen wird, dann könnte es sinnvoll sein, es bei Bedarf bereitzustellen.

2

Abhängig von der Zeit, die es dauert, um die Zählung zu aktualisieren, wenn es ein zeitraubender Prozess ist und Sie Count selten aufrufen, würde ich die Zählung beim Aufruf der Funktion aktualisieren und nicht jedes Mal, wenn Sie die Sammlung ändern.

1

On-Demand ist wohl einfacher und könnte daher allgemein als besser angesehen werden.

Was die Leistung betrifft, werden die meisten Anwendungen den Unterschied wahrscheinlich nicht bemerken. Beide Ansätze haben ihre Rückseiten; die aktuelle Strategie kann zu unnötigen Berechnungen führen, während On-Demand dazu führen kann, dass Sie dieselben Berechnungen mehr als einmal durchführen (andererseits können Kunden Werte von Berechnungen auf eigene Faust speichern und somit doppelte Arbeit vermeiden) . Bei Bedarf werden auch kleinere Objekte erstellt, was theoretisch weniger Cache-Fehler und weniger Speicherbereinigungen zur Folge hat, die die Leistung erheblich beeinträchtigen können. Aber auch das würden die meisten Apps nicht merken, würde ich rechnen.

Übrigens, wenn die Berechnung sehr teuer ist, sollte es nicht in einer Eigenschaft sein, wenn ich mich an die .Net Codierungsrichtlinien richtig erinnere.

Verwandte Themen