2015-02-12 2 views
3

Я играл с LISP в последнее время, и я хочу попытаться оптимизировать ужасно неэффективную рекурсивную функцию, кэшируя ее вывод, поэтому он запускает каждую комбинацию параметров один раз. Я хочу сохранить результаты в хэш-таблицу, используя либо (LIST a b), либо (CONS a b) в качестве ключа. Мой вопрос в том, что это возможно? Документация, которую я прочитал, заставит меня поверить, что, поскольку прочитанный мной документ определяет key как «объект» и определяет «объект» как что-то, что было построено с помощью cons. Поэтому я попробовал.Могут ли объекты CONS использоваться как ключ к хеш-таблице?

(defparameter *table* (make-hash-table)) 
(setf (gethash (list 1 2) *table*) 123) 
(format t "~S~%" (gethash (list 1 2) *table*)) 

И это дает мне NIL, когда я ожидал бы 123. Если я заменяю (list 1 2) на cons, он все равно не работает, но когда я использую простое целое число, он отлично работает.

Я использую GCL 2.6.12

ответ

5
(make-hash-table :test #'equal) 
+1

Работает как очарование. Каково значение по умолчанию 'test'? –

+3

http://www.lispworks.com/documentation/HyperSpec/Body/f_mk_has.htm "test --- обозначение для одной из функций eq, eql, equal или equalp. По умолчанию используется eql." – Baggers

+1

О, черт возьми. У меня была эта точная страница, я клянусь, но я пропустил раздел, где он задает значение по умолчанию. Наверное, это то, что я получаю за не RTFM. * уходит от стыда * –

0

Решение для кэширования результатов функций уже реализован для Common Lisp. Один из них - это память библиотеки, вторая - функциональный кеш, и оба доступны с помощью Quicklisp. Использование бывший так же легко, как определение нормальной функции:

(define-memo-function your-time-consuming-function (arg) 
    (code arg)) 

Для справки, пожалуйста, проверьте https://github.com/fare/fare-memoization.

Смежные вопросы