jaredcdavis / fastnumio

Efficient hex string I/O ops for Common Lisp streams
Other
0 stars 0 forks source link

Some suggestions #1

Open stassats opened 8 years ago

stassats commented 8 years ago

Using lookup tables for conversion is a bit faster:

(defun hex-digit-val (x)
  (declare (type character x)
           (optimize (safety 0) speed))
  (aref #.(let ((map (make-array 55)))
             (loop for i to 15
                   for char = (digit-char i 16)
                   do (setf (aref map (- (char-code char) 48)) i
                            (aref map (- (char-code (char-downcase char)) 48)) i))
             map)
        (- (char-code x) 48)))

is faster on both SBCL and CCL.

(defun hex-digit-to-char¡ (n)
  (declare (type (integer 0 15) n)
           (optimize (safety 0) speed))
  (aref #.(coerce "0123456789ABCDEF" 'simple-vector) n))

is a bit faster too.

But you really should use binary I/O to avoid converting to characters and then doing the encoding conversion when printing.

You can also extend the tables to decode multiple at once.

jaredcdavis commented 8 years ago

Thanks for the suggestions, this does give a nice speedup!

I've pushed f7e54cb9a503fcce9a24e601dc3af0fd6bef3eb4 with a new version of hex-digit-val based on your function and the commit message includes some details about the speedup obtained. I'll look at the writer next.

I agree that binary IO would be faster. It may be worth reconsidering my approach. One nice thing about plain text is that it's easy to read what's actually being sent when debugging our application. Also even if I read 32 (or 64 or however many) bits at a time, I'm not sure how to avoid constructing ephemeral bignums...