Ich habe das Konzept einer Sitzung, die Objekte in verschiedenen Zuständen speichert.
Manchmal muss ich die Sitzung nach Objekten durchsuchen, die einer bestimmten Abfrage entsprechen, aber ich tue dies sehr oft und Leistungstests haben gezeigt, dass es in einigen Bereichen zu einem Engpass wird.
Deshalb möchte ich das Konzept der Indizes in einer Sitzung vorstellen.
Etwas wie ...
%Vor%Ich bin mir jedoch nicht sicher, wie man "Gleichheit" eines Func so testen kann. Offensichtlich möchte ich, dass der Index nur beim ersten Aufruf von GetIndex und nachfolgenden Aufrufen erstellt wird, um ihn nicht erneut zu erstellen.
Wie sollte ich diese intern zuordnen, um Index-Existenz-Suchen durchzuführen?
%Vor%Grundsätzlich sollte ich das ??? speichern. Vielleicht kann ich das nicht mit einem Func tun, aber vielleicht gibt es einen anderen Weg.
Der einfachste Ansatz besteht wahrscheinlich darin, einen Hash der Abfrage zu berechnen und die Ergebnisse mit dem Hash als Schlüssel in Ihr Wörterbuch einzufügen.
Wenn Ihre Abfragen Zeichenfolgen sind, können Sie wahrscheinlich einfach die Funktion string.GetHashCode verwenden, um einen einfachen Hash für die Zeichenfolgedaten zu berechnen. Wenn es sich bei Ihren Abfragen um Linq-Abfragen handelt, wird .GetHashCode wahrscheinlich nicht funktionieren, es sei denn, Linq überschreibt diese Methode explizit, um anstelle des standardmäßigen Objektinstanzzeigers einen Hash für die Ausdrucksbaumstruktur zu berechnen. Die Standardimplementierung von .GetHashCode gibt einfach einen Wert zurück, der von der Objektinstanzidentität im Speicher abgeleitet wird, ohne Berücksichtigung des Dateninhalts des Objekts.
Wenn Ihre Abfragen Zeichenfolgen sind und in der Konstruktion ziemlich einheitlich / konsistent sind, sollte die Berechnung eines einfachen Zeichenfolgenhasens ausreichend sein, um den Abfrageverkehr über den Cache zu reduzieren. Wenn Ihre Abfragen in der Struktur weniger konsistent sind (z. B. äquivalente Abfragen, aber mit Argumenten in anderer Reihenfolge), müssen Sie möglicherweise eine eigene Hashfunktion erstellen, die einen Hashwert in einer kanonisierten Form der Eingabeabfrage berechnet, um die Trefferquoten für Abfragen zu verbessern das sind logisch äquivalent, aber textuell verschieden.
Da Ihre Hash-Berechnung rechenintensiver wird, verringert sich die Leistungssteigerung bei der Verwendung eines Caches. Stellen Sie sicher, dass die Abfrageoperation ausreichend teuer ist, um Rechenzeit zu sparen und Speicher für den Cache zu verbrauchen, um Einsparungen bei der Ausführungszeit zu erzielen. Die Abfrageoperation sollte mindestens 2 oder mehr Größenordnungen größer sein als der Hash-Berechnungs- und Cache-Verwaltungsaufwand. Wenn Ihre Abfrageoperation ein Prozess außerhalb des Prozesses oder netzübergreifend ist, wird Ihr Cache-Overhead mit Sicherheit durch die Kosten der Abfrage in den Schatten gestellt.
Sie könnten die Verwendung eines Expression<Func<K,V>>
und dann von Compile()
des Ausdrucks in Erwägung ziehen müssen ausgeführt werden.
Sehen Sie sich zur Überprüfung der Gleichheit diese SO-Frage an:
Wie überprüfe ich, ob zwei Ausdrücke & lt; Func & lt; T, bool & gt; & gt; sind gleich
Alternativ können Sie den Indizes einen Namen geben und weiterhin den Delegaten verwenden:
%Vor%Der Vergleich von Ausdrücken in Schleifen könnte wahrscheinlich zeitaufwändiger sein als die Auswahl über das Wörterbuch. Wie bereits im Thread gezeigt, gibt es Möglichkeiten, sie zu vergleichen, aber sehr zeitaufwendig und nicht genau:
%Vor%vs
%Vor%vs
%Vor%gibt false
Das Erstellen von Ad-hoc-Indizes ist also keine gute Lösung.
Sie können eine Indexing-Factory-Klasse mit vordefinierten Ausdrucksvorlagen verwenden, die beim ersten Aufruf Ausdrücke für bestimmte Parameterkombinationen erstellen und sie (Instanzen) mit .Equals als Referenz verwenden.
Etwas wie (PseudoC # ode):
%Vor%Speichern Sie dann den Ausdruck als Schlüssel im Wörterbuch mit einer Liste von Ergebnissen, wenn er zuerst ausgeführt wird. Überprüfen Sie bei den folgenden Ausführungen, ob Sie Ergebnisse für diesen Ausdruck zwischengespeichert haben, da Sie bei Verwendung der Factory immer die gleiche Referenz erhalten.
Tags und Links .net c# indexing dictionary