La función:sbcl corre siempre en segunda llamada de la función
Dada una lista de retorno LST todas las permutaciones de los contenidos de la lista exacta de longitud k, que por defecto es la longitud de la lista si no previstos.
(defun permute (lst &optional (k (length lst)))
(if (= k 1)
(mapcar #'list lst)
(loop for item in lst nconcing
(mapcar (lambda (x) (cons item x))
(permute (remove-if (lambda (x) (eq x item)) lst)
(1- k))))))
El problema: estoy usando BABA en emacs conectados a SBCL, no he hecho demasiado personalización aún. La función funciona bien en entradas más pequeñas como lst = '(1 2 3 4 5 6 7 8) k = 3, que es lo que más se utilizará en la práctica. Sin embargo, cuando lo llamo con una entrada grande dos veces seguidas, la segunda llamada nunca regresa y sbcl ni siquiera aparece en la parte superior. Estos son los resultados en el REPL:
CL-USER> (time (nth (1- 1000000) (permute '(0 1 2 3 4 5 6 7 8 9))))
Evaluation took:
12.263 seconds of real time
12.166150 seconds of total run time (10.705372 user, 1.460778 system)
[ Run times consist of 9.331 seconds GC time, and 2.836 seconds non-GC time. ]
99.21% CPU
27,105,349,193 processor cycles
930,080,016 bytes consed
(2 7 8 3 9 1 5 4 6 0)
CL-USER> (time (nth (1- 1000000) (permute '(0 1 2 3 4 5 6 7 8 9))))
Y nunca vuelve de la segunda llamada. Solo puedo adivinar que por alguna razón estoy haciendo algo horrible para el recolector de basura, pero no puedo ver qué. ¿Alguien tiene alguna idea?
¿Algo interesante en tu * buffer inferior-lisp * cuando eso sucede? – Xach
¿por qué no se interrumpe SBCL y mira lo que hace? –
Como una pregunta general para todos los que han respondido.Parece que la cantidad de basura que estoy creando es el problema. ¿Hay algún buen artículo que explique cómo sortear cosas como esta? He hecho algunas cosas que pensé que ayudarían, pero universalmente lo han empeorado mucho. – asm