Skip to content

Instantly share code, notes, and snippets.

@inconvergent
Created June 20, 2019 12:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save inconvergent/c1df519c2b1b2aab64fafe110cc898ef to your computer and use it in GitHub Desktop.
Save inconvergent/c1df519c2b1b2aab64fafe110cc898ef to your computer and use it in GitHub Desktop.
; fastest solution. based on https://bitbucket.org/vityok/cl-faster-input/src/default/
(defun do-lines-as-buffer (fn fx &key (buffer-width 80))
(declare #.*opt-settings* (function fx) (fixnum buffer-width))
"
fx will receive a stream (named in). use it like this:
(loop for x = (read in nil nil)
while x
do something)
"
(let ((*read-default-float-format* 'double-float)
(buffer (make-array buffer-width
:element-type 'character
:initial-element #\space)))
(with-open-file (is fn :direction :input)
(loop for (val pos newl) =
(multiple-value-list (read-line-into-sequence buffer is
:eof-error-p nil))
while val
do (when newl
(with-input-from-string (in val :start 0 :end pos)
(funcall fx in)))))))
;; ----------------------------------------------------------------------
(declaim (inline -maybe-float))
(defun -maybe-float (v)
(declare (number v))
(if (equal (type-of v) 'double-float) v (coerce v 'double-float)))
; (only) slightly slower.
; suggested by lispm in
; https://gist.github.com/inconvergent/8b6ccfbde4fca7844c1962082ef07a7e
(declaim (inline floats-string-to-list))
(defun floats-string-to-list (s end)
(declare #.*opt-settings* (string s))
(let ((*read-default-float-format* 'double-float))
(loop with i of-type fixnum = 0
with start of-type fixnum = 0
with v of-type number = 0
for pos = (loop for i of-type fixnum from start below end
for c of-type character across s
unless (eql c #\space)
do (return i))
while pos do (multiple-value-setq (v start)
(read-from-string s nil nil :start pos))
while v collect (-maybe-float v) of-type double-float)))
(defun do-lines-as-floats (fn fx &key (buffer-width 80))
(declare #.*opt-settings* (function fx) (fixnum buffer-width))
(let ((buffer (make-array buffer-width :element-type 'character
:initial-element #\space)))
(with-open-file (is fn :direction :input)
(loop for (val pos newl) =
(multiple-value-list (read-line-into-sequence buffer is
:eof-error-p nil))
while val do (when newl
(funcall fx (floats-string-to-list val pos)))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment