[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

LispM's great I/O performance



    Date: Wed, 17 Jan 90 11:08:56 -0500
    From: magerman@linc.cis.upenn.edu


	 Can you be more specific about this task.

    Sure.  My data set is a sequence of 1 million pairs of integers.  The
    first in each pair ranges from 0 to 32767, and the second ranges from 0
    to 127.  So, a section of the data might be:
	    3000 12 4562 50 18002 61 456 12 . . .

The following code dumps and loads such data quite nicely.  (About 1
minute each way on my MacIvory using TCP.  I believe that NFS is much
faster, but I can't remember my unix password at the moment to verify
that.)

File I/O wasn't the problem in your example, READ and PRINT were.  I assume
you weren't using READ and PRINT on the Sun 3/50, so you probably
weren't making a valid comparison.

;;; -*- Mode: LISP; Syntax: Common-lisp; Package: USER; Base: 10 -*-

(defun dump-my-array (file array &optional (length (length array)))
  (with-open-file (stream file :direction :output
			       :element-type '(unsigned-byte 16))
    ;; Identify the file with a magic number.
    (send stream :tyo 4529)
    ;; Send the array length.
    (send stream :tyo (ldb (byte 16 16) length))
    (send stream :tyo (ldb (byte 16 0)  length))
    ;; Send the data
    (send stream :string-out array 0 length)
    ;; Return the truename of the file.
    (send stream :truename)))

(defun load-my-array (file &optional array)
  (with-open-file (stream file :element-type '(unsigned-byte 16))
    ;; Check for the magic number.
    (unless (= (send stream :tyi) 4529)
      (error "This file doesn't contain an array."))
    ;; Get the length
    (let ((length (dpb (send stream :tyi) (byte 16 16) (send stream :tyi))))
      ;; Create the array if it wasn't supplied to us.
      ;; If it was supplied, make sure it's big enough.
      (cond ((null array)
	     (setq array (make-array length :element-type '(unsigned-byte 16))))
	    ((> length (length array))
	     (cerror (format nil "Load just the first ~D elements." (length array))
		     "The array supplied, ~S, cannot accomodate the ~D elements in the file"
		     array length)
	     (setq length (length array))))
      ;; Get the data.
      (send stream :string-in nil array 0 length)
      ;; Return the array.
      array)))

;; Benchmark

(defun make-test-array (length &optional (area *default-cons-area*))
  (let ((array (make-array length :element-type '(unsigned-byte 16) :area area)))
    (declare (sys:array-register array))
    (loop for i below length do
      (setf (aref array i) (random (if (evenp i) 32768 128))))
    array))

(defvar *test-array* (make-test-array 1000000. sys:permanent-storage-area))

(defun test-file-io ()
  (cl:time (dump-my-array "J:>dla>trash>test-array.array" *test-array*))
  (cl:time (load-my-array "J:>dla>trash>test-array.array" *test-array*)))