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

Re: MacTCP too slow?!



At 11:33 AM 10/13/94, hsiung wrote:
>The Apple-implementation of stream-tyi which reads the next character
>from the receive-buffer of MacTCP seems extreemly sloooowww. It tooks 
>5-10s to read 18K on my Quadra 700.
>Do you have a better an idea to read the receive-buffer faster?
>
>Alain Hsiung

You can get some speedup by defining a stream-reader method. See the
MCL documentation for more information.

Your code will change from:

(loop
  (let ((char (stream-tyi tcp-stream)))
    (unless char (return))              ; eof
    ...))

to:

(multiple-value-bind (reader arg) (stream-reader tcp-stream)
  (loop
    (let ((char (funcall reader arg)))
      (unless char (return))            ; eof
      ...)))

Here's a first pass at a patch for the mactcp code. I haven't tested
this except to check that it compiles without error. I just moved the
body of the stream-tyi method into the %tcp-stream-tyi function,
checked some types and made a couple little changes to ensure
that the code goes out of line as little as is safe.

You may want to do the same for the stream-tyo method.

------------------------------------------------------------------------

; tcp-tyi-speedup.lisp
;
; Provide a stream-reader for TCP streams

(in-package :ccl)

(eval-when (:compile-toplevel :execute :load-toplevel)
  (require "MACTCP"))

(defmethod stream-tyi ((s tcp-stream))
  (%tcp-stream-tyi
   (require-type (tcp-stream-conn s) 'conn)))

(defun conn-tcp-stream (conn)
  (dolist (s *open-tcp-streams*)
    (when (eq conn (tcp-stream-conn s))
      (return s))))

(defun %tcp-stream-tyi (conn)
  (declare (type conn conn))
  (locally
    (declare (optimize (speed 3) (safety 0)))
    (without-interrupts
     (if (conn-untyi-char conn)
       (prog1 (conn-untyi-char conn) (setf (conn-untyi-char conn) nil))
       (progn
         (when (eql (conn-read-count conn) 0)
           (let* ((pb (conn-pb conn))
                  (rds (conn-rds conn)))
             (%tcp-nocopyrcv pb rds (conn-rds-entries conn) (conn-read-timeout conn))
             (when (eql 0 (setf (conn-read-count conn) (ccl:%get-word rds)))
               (tcp-stream-bfr-return conn)
               (when (tcp-stream-eofp conn)    ;Can't get a character.
                 (return-from %tcp-stream-tyi nil))
               (error "Can't read a character from ~S"
                      (conn-tcp-stream conn)))
             (ccl:%setf-macptr (conn-read-bufptr conn) (ccl:%get-ptr rds 2))
             (setf (conn-rds-offset conn) 6)))
         (prog1 (%code-char (ccl:%get-byte (conn-read-bufptr conn)))
           (ccl:%incf-ptr (conn-read-bufptr conn))
           (when (eql (setf (conn-read-count conn)
                            (the fixnum (1- (the fixnum (conn-read-count conn)))))
                      0)
             (let* ((rds (conn-rds conn))
                    (nextbuf (conn-rds-offset conn))
                    (bufptr (conn-read-bufptr conn)))
               (if (eql (setf (conn-read-count conn) (ccl:%get-word rds nextbuf)) 0)
                 (tcp-stream-bfr-return conn)
                 (progn
                   (ccl:%setf-macptr bufptr (ccl:%get-ptr rds (+ nextbuf 2)))
                   (setf (conn-rds-offset conn) (+ nextbuf 6))))))))))))

(defmethod stream-reader ((stream tcp-stream))
  (values #'%tcp-stream-tyi
          (require-type (tcp-stream-conn stream) 'conn)))