Warum "iteriert" das Prelude nicht den Knoten?

8

Warum iterate nicht definiert wie

%Vor%

im Vorspiel?

    
user3237465 20.06.2015, 01:39
quelle

3 Antworten

11

Wenn man den Knoten so bindet, scheint das Teilen nicht zu erhöhen.

Kontrast mit:

%Vor%

Wenn Sie hier den Knoten verknoten, wird eine kreisförmige Liste im Speicher erstellt. x ist ein eigener Schwanz. Es gibt einen echten Gewinn.

Ihre vorgeschlagene Implementierung erhöht nicht die Freigabe gegenüber der naiven Implementierung. Und dafür gibt es keine Möglichkeit - es gibt keine gemeinsame Struktur in etwas wie iterate (+1) 0 auf jeden Fall.

    
Carl 20.06.2015, 02:07
quelle
6

Es gibt keine Knotenbindung in Ihrer Version, es wird lediglich ein Zeiger auf der produzierten Liste gehalten, um den Eingabewert für die nächste Iteration zu finden. Dies bedeutet, dass jede Listenzelle nicht gc-ediert werden kann, bis die nächste Zelle erzeugt ist.

Im Gegensatz dazu verwendet die Version des Preludes den Call-Frame von iterate , und da er nur einmal benötigt wird, könnte ein guter Compiler diesen einen Frame wiederverwenden und den Wert darin mutieren, um den gesamten Betrieb (und Lists) zu optimieren Zellen sind in diesem Fall unabhängig voneinander).

    
Will Ness 20.06.2015 02:55
quelle
2

Die Prelude-Definition, die ich der Übersichtlichkeit halber hier einfüge, benötigt keinen Overhead, um die Map aufzurufen.

%Vor%

Nur zum Spaß habe ich ein kleines schnelles Programm gemacht, um eure iterate gegen die Preludes zu testen - nur um auf die normale Form take 100000000 $ iterate (+1) 0 zu reduzieren (dies ist eine Liste von Int s). Ich habe nur 5 Tests durchgeführt, aber deine Version lief für 7.833 (max 7.873 min 7.667 ), während das Preludes bei 7.519 (max 7.591 min 7.477 ) lief. Ich vermute, der Zeitunterschied ist der Overhead von map , der aufgerufen wird.

Der zweite Grund ist einfach: Lesbarkeit.

    
Alec 20.06.2015 02:35
quelle

Tags und Links