Created
June 20, 2019 12:54
-
-
Save inconvergent/c1df519c2b1b2aab64fafe110cc898ef to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; 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