2016-09-18 2 views
1

У меня есть объект o, который является экземпляром класса X в SBCL.Как сериализовать и загрузить объект в SBCL/Common Lisp

Я хочу функцию write-X-object, которая сериализует o в файл таким образом, что, когда этот файл считывается с помощью объекта load-X, результирующий объект эквивалентен o.

;; writing the object 
(write-X-object o "~/tmp/o.serialized") 

;; reading the object, much later, 
;; after sbcl has been exited and restarted 

(setq v (read-X-object "~/tmp/o.serialized")) 

о может быть около гигабайта в размере (или массив несколько миллионов меньше объектов), со сложной структурой, так что идея для чтения и записи, чтобы быть как можно быстрее.

+1

Проверьте https://github.com/conspack/cl-conspack – PuercoPop

ответ

2

Есть три основных способа сделать это

  1. использовать встроенный в учреждениях печати/чтения: вы можете определить метод print-object для вашего класса, который бы сериализация его (возможно, вы бы это зависит от некоторые специальные переменные, поэтому вы не печатаете гигабайты в repl). Затем вы можете определить макрос читателя (соответствующий любому синтаксису, который вы используете для печати вашего объекта), затем, чтобы сохранить свой объект, вы сделали бы (with-open-file (x "/tmp/foo" :direction :output) (print my-object X)), и, чтобы вернуть его, вы сделали бы (with-open-file (x "/tmp/foo") (read x). Плюсы в том, что это просто. Недостатки в том, что это медленное и не экономичное пространство.
  2. Вы можете воспользоваться сторонней библиотекой сериализации, такой как conspack, которую предложил комментатор. Плюсы: достаточно быстро читать или писать. Минусы: вы не можете пошаговое чтение объекта, большего, чем память.
  3. Вы можете реструктурировать свой класс (используя MOP), чтобы объект можно было сохранить в памяти и на диске в том же формате, а затем использовать mmap для его чтения/записи. Примерная библиотека для этого - manardb. Эта система также позволяет хранить много разных объектов. Плюсы: нет накладных расходов на чтение/запись на диск. Может обрабатывать объекты, большие, чем основная память, автоматически (ручка для обмена). Минусы: могут быть небольшие накладные расходы для доступа к полям объекта. Обратите внимание, что с помощью этого метода обычно можно избежать большинства недостатков, используя реализацию, которая может правильно оптимизировать доступ с помощью указателей ffi и используя специализированные структуры данных (например, массив с плавающей точкой намного лучше, чем общий массив)
+0

Спасибо. Чтобы быть ясным, я стараюсь избегать варианта 1 по нескольким причинам: он медленный, он неэффективен в пространстве, и это сложность в коде. Я рассмотрю вариант 2. – kdog

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