Ich versuche, Lisp/Scheme zu lernen, und ich versuchte, eine sehr einfache Version des Mandelbrot-Set darin zu implementieren, um Praxis zu bekommen. Das Problem, auf das ich stieß, ist, dass der Code sehr, sehr langsam läuft. Zuerst dachte ich, es wäre, weil ich Rekursion anstelle von Imperativ-Schleifen verwendete, aber ich habe versucht, mehr oder weniger den gleichen Code (Rekursion eingeschlossen) in Python (der nicht einmal Tail-Call-Optimierung hat) zu schreiben, und es lief sehr glattMandelbrot-Set-Implementierung in Scheme ist sehr langsam
So frage ich mich, ob es etwas offensichtlich ist, das ich in meinem Code vermisse und was ich tun könnte, um es schneller laufen zu lassen.
Hier ist das Code-Snippet in Scheme (Racket). Ich habe auch so ziemlich die gleiche Sache in SBCL und die Geschwindigkeit war vergleichbar
#lang racket
(define-syntax dotimes
(syntax-rules()
((_ (var n res) . body)
(do ((limit n)
(var 0 (+ var 1)))
((>= var limit) res)
. body))
((_ (var n) . body)
(do ((limit n)
(var 0 (+ var 1)))
((>= var limit))
. body))))
(define (print-brot zr zc)
(if (< (+ (* zr zr) (* zc zc)) 2)
(display "@")
(display ".")))
(define (brot zr zc cr cc i)
(if (= i 0)
(print-brot zr zc)
(let ((z2r (- (* zr zr) (* zc zc))) (z2c (* 2 zr zc)))
(brot (+ z2r cr) (+ z2c cc) cr cc (- i 1)))))
(define (linspace i w)
(/ (- i (/ w 2)) (/ w 4)))
(define (brot-grid w h n)
(dotimes (i w)
(dotimes (j h)
(let ((x (linspace i w)) (y (linspace j h)))
(brot 0 0 x y n)))
(newline)))
(brot-grid 40 80 20)
(ich der Codeblock hoffen, nicht zu clustery ist, war es schwer, es zu etwas einfacher strippen)
Auch Ich weiß, Scheme und Common Lisp haben komplexe Zahlen eingebaut, aber ich wollte es mit regulären reellen Zahlen testen, ich glaube nicht, dass dies der Grund ist, warum es so langsam läuft.
Der Parameter "i" der Brot-Funktion ist die Anzahl der Iterationen, und der Parameter "n" von Brot-Grid ist auch die Anzahl der Iterationen für jeden Punkt. Wenn ich es auf mehr als 10 setze, dauert der Code für immer, was nicht normal erscheint. Die Zunahme der Zeit scheint auch nicht linear zu sein, zum Beispiel dauert es nur ungefähr eine Sekunde auf meiner Maschine mit n = 10, dauert aber mehrere Minuten mit n = 15 und endet nicht einmal mit n = 20
Also, was macht diesen Code so langsam?
Vielen Dank im Voraus
Soll 'zr' und' zc' sehr groß sein? Ich habe es an einem Punkt pausiert und 'zr' hatte über 4000 Ziffern. Da Scheme BigIntegers hat, wird es sich über die Größe nicht beschweren, bis der gesamte Programmspeicher verbraucht ist. – Sylwester
'reelle Zahlen'? Schwimmt? Wenn Sie mit reellen/Gleitkommazahlen rechnen möchten, sollten Sie sicherstellen, dass Sie sie tatsächlich verwenden und dass Ihre Operationen diese auch verwenden. Ich sehe viele ganzzahlige und rationale Operationen, die möglicherweise langsam sind, zum Beispiel bei der Verwendung von Bignums oder großen rationalen Operationen. Verfolgen Sie einfach die Funktionen und sehen Sie, welche Zahlen die Funktionen verwenden. –
Mehr als 10 Iterationen? Pshaw, stell dir 1000 vor! Selbst wenn Sie * wirklich bissige * Wege zur Iteration implementieren können, wird die Erzeugung eines Mset langsam sein. Wenn Sie es nur auf einfache Weise codieren, wird es * sehr * langsam. Es ist rechenintensiv, also brauchen Sie vielleicht eine bessere Sprachwahl. Und Sie brauchen keine komplexen Zahlenfunktionen, Sie brauchen nur sehr schnelle Methoden, um entweder Festkomma-Ganzzahlen oder echte FPU-Zahlen zu manipulieren. –