Leistung von "all" in haskell

7

Ich hatte fast keine Ahnung von Haskell und versuchte einige Project Euler Probleme zu lösen. Beim Lösen von Nummer 5 habe ich diese Lösung (für 1..10) geschrieben

%Vor%

Nun habe ich herausgefunden, dass all wie folgt implementiert ist:

%Vor%

Heißt das nicht, dass die Bedingung für jedes Element überprüft wird? Wäre es nicht viel schneller, das erste falsche Ergebnis der Krankheit zu brechen? Dies würde die Ausführung des obigen Codes beschleunigen.

Danke

    
theomega 17.07.2010, 15:24
quelle

4 Antworten

20

and selbst ist kurzgeschlossen und da sowohl die map als auch die all Auswertung faul ist, erhalten Sie nur so viele Elemente wie nötig - nicht mehr.

Sie können dies mit einer GHCi -Sitzung überprüfen:

%Vor%     
viraptor 17.07.2010, 15:35
quelle
4

map wertet nicht alle Argumente aus, bevor and ausgeführt wird. Und and ist kurzgeschlossen.

Beachten Sie, dass in GHC all nicht wirklich so definiert ist.

%Vor%

Wir sehen all p (x:xs) = p x && all p xs . Wenn also p x falsch ist, wird die Auswertung gestoppt.

Darüber hinaus gibt es eine Vereinfachungsregel all/build , die Ihre all p [1..max] effektiv in eine einfache Fail-Fast-Schleife * umwandelt. Ich glaube also nicht, dass Sie viel von all verbessern können.

*. Der vereinfachte Code sollte wie folgt aussehen:

%Vor%

    
kennytm 17.07.2010 15:32
quelle
4

Dies ist ein gutes Programm für die Fusionsoptimierung, da alle Ihre Schleifen als kombinierbare Kombinationen dargestellt werden. So können Sie es z. Data.Vector, und erzielen Sie eine bessere Leistung als mit Listen.

Ab N = 20, mit Listen wie in Ihrem Programm:

  • 52.484s

Verwenden Sie auch rem anstelle von mod .

  • 15.712s

Wo die Listenfunktionen Vektoroperationen werden:

%Vor%     
Don Stewart 17.07.2010 17:40
quelle
1

Sie gehen davon aus, dass and nicht kurzschließt. and stoppt die Ausführung beim ersten false Ergebnis, das es sieht, also ist es "schnell" wie man es erwarten könnte.

    
Mark Rushakoff 17.07.2010 15:29
quelle

Tags und Links