teure Berechnung, die sowohl in isDefined als auch in Apply einer PartialFunction auftritt

8

Es ist durchaus möglich, dass um zu wissen, ob eine Funktion zu irgendeinem Zeitpunkt definiert ist, ein wesentlicher Teil der Berechnung ihres Werts durchgeführt werden muss. In einem PartialFunction müssen beide Methoden bei der Implementierung von isDefined und apply dies tun. Was ist zu tun, ist diese gemeinsame Arbeit teuer?

Es gibt die Möglichkeit, sein Ergebnis zwischenzuspeichern, in der Hoffnung, dass apply nach isDefined aufgerufen wird. Definitiv hässlich.

Ich wünsche mir oft, dass PartialFunction[A,B] Function[A, Option[B]] wäre, was eindeutig isomorph ist. Oder vielleicht könnte es eine andere Methode in PartialFunction geben, sagen wir applyOption(a: A): Option[B] . Bei einigen Mixins hätten Implementierer die Wahl, entweder isDefined und apply oder applyOption zu implementieren. Oder alle auf der sicheren Seite, leistungsorientiert. Clients, die isDefined vor dem Aufruf von apply testen, sollten stattdessen applyOption verwenden.

Das ist jedoch nicht so. Einige der wichtigsten Methoden in der Bibliothek, darunter collect in Sammlungen, benötigen ein PartialFunction . Gibt es einen sauberen (oder nicht so sauberen) Weg, um Berechnungen zu vermeiden, die zwischen isDefined und apply wiederholt werden?

Ist die Methode applyOption(a: A): Option[B] auch sinnvoll? Klingt es machbar, es in einer zukünftigen Version hinzuzufügen? Wäre es das wert?

    
Didier Dupont 18.08.2011, 20:18
quelle

4 Antworten

4

Warum ist Caching so ein Problem? In den meisten Fällen haben Sie eine lokale Berechnung. Wenn Sie also einen Wrapper für das Caching schreiben, müssen Sie sich keine Gedanken darüber machen. Ich habe den folgenden Code in meiner Dienstprogrammbibliothek:

%Vor%

und dann, wenn ich eine teure Berechnung habe, schreibe ich eine Funktionsmethode A => Option[B] und mache etwas wie (f _).drop , um es in collect oder whatnot zu verwenden. (Wenn Sie es inline machen wollten, könnten Sie eine Methode erstellen, die A=>Option[B] übernimmt und eine Teilfunktion zurückgibt.)

(Die umgekehrte Transformation - von PartialFunction nach A => Option[B] - heißt Heben, daher ist der "Tropfen"; ich glaube, ein "unlift" ist ein weit verbreiteter Begriff für die entgegengesetzte Operation.) p>     

Rex Kerr 18.08.2011, 21:15
quelle
3

Schauen Sie sich diesen Thread an, Teilfunktion neu denken . Du bist nicht der Einzige, der sich darüber Gedanken macht.

    
Alex Cruise 19.08.2011 00:06
quelle
2

Das ist eine interessante Frage, und ich gebe meine 2 Cent.

Erstens widerstehen Sie dem Drang nach voreiliger Optimierung. Stellen Sie sicher, dass die Teilfunktion das Problem ist. Ich war erstaunt, wie schnell sie in einigen Fällen sind.

Nun angenommen, es gibt ein Problem, wo käme es her?

  1. Könnte eine große Anzahl von Fallklauseln sein
  2. Komplexe Mustererkennung
  3. Eine komplexe Berechnung der if causes

Eine Option Ich würde versuchen, Wege zu finden, schnell zu versagen. Brechen Sie die Mustererkennung in die Ebene und verketten Sie dann Teilfunktionen. Auf diese Weise können Sie das Spiel vorzeitig beenden. Extrahieren Sie auch wiederholtes Sub-Matching. Zum Beispiel:

Nehmen wir an, OddEvenList ist ein Extraktor, der eine Liste in eine ungerade Liste und eine gerade Liste aufteilt:

%Vor%

Brechen Sie in zwei Teile, einen Teil, der mit dem Teilungswert übereinstimmt, und einen Teil, der versucht, mit dem Ergebnis übereinzustimmen (um wiederholte Berechnungen zu vermeiden. Dies erfordert jedoch ein gewisses Reengineering.

%Vor%

Ich habe dies beim progressiven Lesen von XML-Dateien verwendet, die ein ziemlich unbeständiges Format haben.

Eine weitere Möglichkeit besteht darin, Teilfunktionen mit andThen zu erstellen. Obwohl hier ein schneller Test gezeigt wurde, um anzuzeigen, dass nur der erste Test tatsächlich getestet wurde.

    
Thomas 18.08.2011 21:34
quelle
0

Es ist absolut nichts falsch mit Caching-Mechanismus innerhalb der Teilfunktion, wenn:

  1. Die Funktion gibt immer dieselbe Eingabe zurück, wenn das Argument
  2. übergeben wird
  3. es hat keine Nebenwirkungen
  4. es ist komplett vom Rest der Welt verborgen

Eine solche zwischengespeicherte Funktion kann nicht von einer einfachen alten reinen Partialfunktion unterschieden werden ...

    
paradigmatic 18.08.2011 22:34
quelle

Tags und Links