Frage

Ich habe auf Postsharp (nicht von Magie) entschieden Attribute und memoize Funktionen zu lesen . Der Hash-Wert des Funktionsaufrufs ist der Schlüssel und die zwischengespeicherte (in Geschwindigkeit ) Ergebnis wird statt dem Aufruf der Funktion wieder zurückgeführt werden. Kinderleicht, Mac- und geschmacklos.

Ich habe bereits gegebenen up auf in der Lage, Nebenwirkungen in dekorierten Funktionen zu erfassen, die ein „hartes Problem“ entpuppte mich, auch für die Experten, die ich bin sicher nicht. Als nächstes, ich habe, um herauszufinden, was andere Funktionen Kandidaten für memoization sind.

  • Was über Methoden, die komplexen Referenztypen als Parameter übernehmen?
  • Wie sieht es Methoden, die innerhalb der Instanzen auf Daten hängen sie von genannt werden?

Active-artige Datenobjekte kommen an diesem letzten in dem Sinne.

Bin ich gehen zu müssen, Wochen alten Code Refactoring memoization zu unterstützen?

War es hilfreich?

Lösung

Sie können nur dann eine Funktion memoize, wenn alle seine Eingänge Werttypen oder unveränderliche Referenztypen sind, wenn sie entweder einen Werttyp oder eine neue Instanz eines Referenztyp zurückgibt, und wenn es keine Nebenwirkungen hat. Period.

memoization hängt von einem deterministischen Mapping zwischen den Eingängen und Ausgängen. Jeder Anruf F(a, b, c) in welcher A, b und c die gleichen Werte enthält das gleiche Ergebnis, um memoization Rückkehr möglich sein.

Wenn ein Parameter ein Referenztyp ist, dann, auch wenn ihr Wert nicht ändert, mehr Anrufe auf die Funktion, die sie mit einem anderen Ergebnis führen können. Ein einfaches Beispiel:

public int MyFunction(MyType t)
{
   return t.Value;
}

Console.WriteLine(MyFunction(t));
t.Value++;
Console.WriteLine(MyFunction(t));

Und falls eine Funktion auf einem Wert außerhalb davon abhängt, dann mehrere Anrufe an diese Funktion mit den gleichen Parametern können unterschiedliche Ergebnisse:

int Value = 0;

public int MyFunction(int input)
{
   return Value;
}

Console.WriteLine(MyFunction(1));
Value++;
Console.WriteLine(MyFunction(1));

Und der Himmel helfen Ihnen, wenn Ihre memoized Funktion etwas anderes tut, als einen Wert zurückgeben oder einen neuen Referenz-Typ:

int Value = 0;

public int MyFunction(int input)
{
   Value++;
   return input;
}

Wenn Sie diese Funktion 10 Mal aufrufen, wird Value 10. sein, wenn Sie es Refactoring memoization zu verwenden und nennen es dann 10-mal wird Value 1 sein.

Du kannst den Weg herauszufinden, gehen nach unten, wie Zustand memoize, so dass Sie gefälschte eine Funktion auf, die einen Referenztyp memoizes. Aber was du wirklich memoizing ist die Menge der Werte, die die Funktion arbeitet an. Sie können in ähnlicher Weise eine memoized Funktion hacken, die Nebenwirkungen, so dass die Nebenwirkungen auftreten, bevor die memoization hat. Aber das ist alles für Probleme betteln.

Wenn Sie memoization in eine Funktion implementieren möchten, die eine Referenz-Typ nimmt, der richtige Ansatz ist, die Teil der Funktion Refactoring aus, die auf Werttypen nur funktioniert, und memoize diese Funktion, z.

public int MyFunction(MyType t)
{
   return t.Value + 1;
}

folgt aus:

public int MyFunction(MyType t)
{
   return MyMemoizableFunction(t.Value);
}

private int MyMemoizableFunction(int value)
{
   return value + 1;
}

Jeder anderer Ansatz zur Umsetzung memoization, die Sie entweder a) macht die gleichen, durch Unbekanntes Mittel, oder b) wird nicht funktionieren.

Andere Tipps

Nun, jede Funktion, theoretisch, ist ein Kandidat für memoization. Beachten Sie jedoch, dass memoization für Geschwindigkeit alles über Handelsfläche ist -

In der Regel bedeutet dies, dass, je mehr Staat eine Funktion erfordert oder hängt davon ab, um eine Antwort zu berechnen, desto höher die Raumkosten, die die Wünschbarkeit reduziert die Methode memoize.

Ihre beiden Beispiele sind grundsätzlich Fälle, in denen mehr Staat gerettet werden müßte. Dies hat zwei Nebenwirkungen.

Als erstes wird dies viel mehr Speicherplatz benötigen, um die Funktion memoize, da mehr Informationen müssen gespeichert werden.

verlangsamen

Zweitens wird dies möglicherweise die memoized Funktion, da die den Raum größer, desto höher die Kosten der Nachschlag der Antwort, sowie die höheren Kosten bei der Suche nach, ob ein Ergebnis wurde zuvor gespeichert.

Generell neige ich dazu nur Funktionen zu berücksichtigen, die nur wenige haben möglichen Eingaben und geringe Speicheranforderungen, es sei denn es eine sehr hohe Kosten ist die Antwort bei der Berechnung.

Ich acknoledge, dass diese vage, aber dieser Teil der „Kunst“ in der Architektur ist. Es gibt keine „richtige“ Antwort, ohne beiden Optionen der Umsetzung (memozied und nicht-memoized Funktionen), Profilierung und Messen.

Sie haben schon gedacht eine Art und Weise eine AOP-Lösung bereitzustellen memoization um Funktion Foo zu schaffen, so etwas ist es, herauszufinden, links?

Ja, können Sie ein Objekt beliebiger Komplexität als Parameter an eine memoized Funktion, übergeben, solange es unveränderlich ist, wie alle Dinge, die es hängt davon ab. Auch dies statisch im Moment gar nicht so einfach ist, zu entdecken.

Sind vermählen Sie noch auf die Idee, dass Sie statisch den Code, um Ihre Benutzer über die Frage beraten untersuchen können „Ist es eine gute Idee, memoization anzuwenden Foo zu funktionieren?“

Wenn Sie machen, dass eine Ihre Anforderungen erhalten Sie eine globale Forschungsanstrengung beitreten, die bisher viele Jahre gedauert hat. Hängt davon ab, wie ehrgeizig Sie sind, glaube ich.

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