Wie erstelle ich Daten für Criterion-Benchmarks?

9

Ich verwende das Kriterium , um meinen Haskell-Code zu bewerten. Ich mache einige schwere Berechnungen, für die ich zufällige Daten brauche. Ich habe meine Haupt-Benchmark-Datei folgendermaßen geschrieben:

%Vor%

Ich halte Benchmarks und Datengeneratoren für sie in verschiedenen Modulen:

%Vor%

Das funktioniert, aber ich habe zwei Bedenken. Erstens, ist die Zeit erforderlich, um Zufallsdaten zu generieren, die in der Benchmark enthalten sind? Ich fand eine Frage, die dieses Thema berührt Aber ehrlich gesagt kann ich es nicht auf meinen Code anwenden. Um zu überprüfen, ob das passiert, habe ich eine alternative Version meines Datengenerators geschrieben, die in IO monad enthalten ist. Ich legte Benchmark-Liste mit Main, genannt der Generator, extrahiert das Ergebnis mit & lt; - und dann an die Benchmark-Funktion übergeben. Ich sah keinen Unterschied in der Leistung.

Meine zweite Sorge betrifft die Generierung von Zufallsdaten. Momentan wird der Generator, der einmal erstellt wurde, nicht aktualisiert, was dazu führt, dass dieselben Daten in einem einzigen Lauf erzeugt werden. Das ist kein großes Problem, aber trotzdem wäre es schön, es richtig zu machen. Gibt es eine gute Möglichkeit, verschiedene Zufallsdaten innerhalb jeder Daten * -Funktion zu erzeugen? "Ordentlich" bedeutet "ohne Datenfunktionen zu machen, die StdGen innerhalb von IO erwerben"?

BEARBEITEN: Wie im Kommentar unten erwähnt, ist mir die Zufälligkeit der Daten nicht wirklich wichtig. Für mich ist wichtig, dass die Zeit, die für die Generierung der Daten benötigt wird, nicht im Benchmark enthalten ist.

    
Jan Stolarek 15.10.2012, 13:05
quelle

2 Antworten

5
  

Das funktioniert, aber ich habe zwei Bedenken. Erstens, ist die Zeit, die benötigt wird, um zufällige Daten in der Benchmark enthalten zu generieren?

Ja, würde es. All die zufällige Generation sollte träge passieren.

  

Um zu überprüfen, ob das passiert, habe ich eine alternative Version meines Datengenerators geschrieben, die in IO monad enthalten ist. Ich legte Benchmark-Liste mit Main, genannt der Generator, extrahiert das Ergebnis mit & lt; - und dann an die Benchmark-Funktion übergeben. Ich sah keinen Unterschied in der Leistung.

Das wird erwartet (wenn ich verstehe, was du meinst); Die Zufallswerte von randoms gen werden erst erzeugt, wenn sie benötigt werden (d. h. innerhalb Ihrer Benchmark-Schleife).

  

Gibt es eine gute Möglichkeit, verschiedene Zufallsdaten innerhalb jeder Daten * -Funktion zu erzeugen? "Ordentlich" bedeutet "ohne Datenfunktionen zu machen, die StdGen innerhalb von IO erwerben"?

Sie müssen entweder in IO sein oder ein StdGen mit einem ganzzahligen Startwert, den Sie angeben, mit mkStdGen erstellen.

Re. Ihre Hauptfrage, wie Sie die pRNG-Inhalte aus Ihren Benchmarks herausholen sollten, sollten Sie in der Lage sein, die zufällige Eingabe vollständig vor Ihrer defaultMain (benchmarks g) -Stuff zu bewerten, mit evaluate und force like:

%Vor%

wobei force sein Argument zur normalen Form auswertet, aber das wird immer noch träge passieren. Um es außerhalb von bench auszuwerten, verwenden wir evaluate , um die monadische Sequenzierung zu nutzen. Du könntest auch Dinge wie den Aufruf von seq am Ende jeder der Listen in deinem Tupel usw. tun, wenn du die Importe vermeiden willst.

So etwas sollte gut funktionieren, es sei denn, Sie müssen eine große Menge an Testdaten im Speicher halten.

BEARBEITEN : Diese Methode ist auch eine gute Idee, wenn Sie Ihre Daten von IO beziehen möchten, wie z. B. das Lesen von der Festplatte, und dies nicht in Ihre Benchmarks integrieren möchten.

>     
jberryman 15.10.2012, 13:37
quelle
0

Sie könnten stattdessen versuchen, die Zufallsdaten aus einer Datei zu lesen. (Wenn Sie auf einem Unix-ähnlichen Betriebssystem arbeiten, können Sie sogar /dev/urandom verwenden.)

Je nachdem, wie viele Daten Sie benötigen, kann die I / O-Zeit jedoch die Berechnungszeit verkürzen. Es hängt davon ab, wie viele zufällige Daten Sie benötigen.

(Wenn Ihr Benchmark beispielsweise Zufallszahlen liest und deren Summe berechnet, wird er I / O-begrenzt sein. Wenn Ihr Benchmark eine Zufallszahl liest und einige Berechnungen basierend auf genau dieser einen Zahl durchführt, wird der I / O fügt überhaupt keinen Overhead hinzu.)

    
MathematicalOrchid 15.10.2012 19:11
quelle

Tags und Links