me encontré con este código en Clojure a cribar primeros n números primos:¿Por qué Clojure es mucho más rápido que mit-scheme para funciones equivalentes?
(defn sieve [n]
(let [n (int n)]
"Returns a list of all primes from 2 to n"
(let [root (int (Math/round (Math/floor (Math/sqrt n))))]
(loop [i (int 3)
a (int-array n)
result (list 2)]
(if (>= i n)
(reverse result)
(recur (+ i (int 2))
(if (< i root)
(loop [arr a
inc (+ i i)
j (* i i)]
(if (>= j n)
arr
(recur (do (aset arr j (int 1)) arr)
inc
(+ j inc))))
a)
(if (zero? (aget a i))
(conj result i)
result)))))))
Entonces escribí el equivalente (creo) el código en el esquema (I utilizará MIT-esquema)
(define (sieve n)
(let ((root (round (sqrt n)))
(a (make-vector n)))
(define (cross-out t to dt)
(cond ((> t to) 0)
(else
(vector-set! a t #t)
(cross-out (+ t dt) to dt)
)))
(define (iter i result)
(cond ((>= i n) (reverse result))
(else
(if (< i root)
(cross-out (* i i) (- n 1) (+ i i)))
(iter (+ i 2) (if (vector-ref a i)
result
(cons i result))))))
(iter 3 (list 2))))
El de temporización resultados son: Para Clojure:
(time (reduce + 0 (sieve 5000000)))
"Elapsed time: 168.01169 msecs"
Para mit-esquema:
(time (fold + 0 (sieve 5000000)))
"Elapsed time: 3990 msecs"
¿Alguien puede decirme por qué mit-scheme es más de 20 veces más lento?
Gracias por hacer este tipo de comparación. Creo que ayuda a ambos idiomas. – octopusgrabbus
Creo que el código de su Esquema es incorrecto. En particular, 'make-vector' llenará el vector con' 0', que se trata como * true * en Scheme. Cambiarlo a '(make-vector n #f)' produce resultados mucho más sensatos. –
(make-vector n) se completa con #f in mit-scheme. –