Функция:SbCl работает вечно на втором вызове функции
дан список возврата LST все перестановки содержимого входящих в список точно длины к, который по умолчанию длина списка, если не предусмотрено.
(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))))))
Проблема: Я использую SLIME в Emacs, связанных с SBCL, я не сделал слишком много настроек еще. Функция отлично работает на меньших входах, таких как lst = '(1 2 3 4 5 6 7 8) k = 3, что и будет использоваться на практике. Однако, когда я вызываю его с большим вводом дважды подряд, второй вызов никогда не возвращается и sbcl даже не отображается вверху. Это результаты в 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))))
И он никогда не возвращается со второго вызова. Я могу только догадываться, что по какой-то причине я делаю что-то ужасное для сборщика мусора, но я не вижу, что. У кого-нибудь есть идеи?
Что-нибудь интересное в вашем * нижнем lisp * буфере, когда это происходит? – Xach
Почему бы не прервать SBCL и посмотреть на обратную линию, что он делает? –
Как общий вопрос всем, кто ответил.Это похоже на то количество мусора, которое я создаю, это проблема. Есть ли хорошие статьи, объясняющие, как обойти такие вещи? Я сделал некоторые вещи, которые, как я думал, помогли бы, но повсеместно они на самом деле сделали это намного хуже. – asm