io: speed up read-line a little

This commit is contained in:
Matthew Flatt 2019-01-19 07:38:06 -07:00
parent 962c7d4397
commit a2b1fbea3f
3 changed files with 37 additions and 27 deletions

View File

@ -18,7 +18,9 @@
peek-bytes! peek-bytes!
peek-bytes-avail! peek-bytes-avail!
peek-bytes-avail!* peek-bytes-avail!*
peek-bytes-avail!/enable-break) peek-bytes-avail!/enable-break
do-read-byte/core-port)
(module+ internal (module+ internal
(provide do-read-bytes!)) (provide do-read-bytes!))
@ -49,10 +51,13 @@
(define/who (read-byte [orig-in (current-input-port)]) (define/who (read-byte [orig-in (current-input-port)])
(check who input-port? orig-in) (check who input-port? orig-in)
(let ([in (->core-input-port orig-in)]) (let ([in (->core-input-port orig-in)])
(do-read-byte/core-port who in)))
(define (do-read-byte/core-port who in)
(define read-byte (core-input-port-read-byte in)) (define read-byte (core-input-port-read-byte in))
(cond (cond
[read-byte (do-read-byte who read-byte in)] [read-byte (do-read-byte who read-byte in)]
[else (read-byte-via-bytes in #:special-ok? #f)]))) [else (read-byte-via-bytes in #:special-ok? #f)]))
(define/who (read-bytes amt [in (current-input-port)]) (define/who (read-bytes amt [in (current-input-port)])
(check who exact-nonnegative-integer? amt) (check who exact-nonnegative-integer? amt)

View File

@ -1,5 +1,6 @@
#lang racket/base #lang racket/base
(require "../common/check.rkt" (require racket/fixnum
"../common/check.rkt"
"input-port.rkt" "input-port.rkt"
"bytes-input.rkt" "bytes-input.rkt"
"string-input.rkt" "string-input.rkt"
@ -16,23 +17,24 @@
(define-syntax-rule (define-read-line read-line (define-syntax-rule (define-read-line read-line
make-string string-length string-set! make-string string-length string-set!
string-copy! substring string-copy! substring
read-char peek-char do-read-char peek-char
as-char) as-char)
(define/who (read-line [in (current-input-port)] [mode 'linefeed]) (define/who (read-line [orig-in (current-input-port)] [mode 'linefeed])
(check who input-port? in) (check who input-port? orig-in)
(check who ok-mode? #:contract ok-mode-str mode) (check who ok-mode? #:contract ok-mode-str mode)
(define in (->core-input-port orig-in))
(maybe-flush-stdout in) (maybe-flush-stdout in)
(define cr? (memq mode '(return any any-one))) (define cr? (memq mode '(return any any-one)))
(define lf? (memq mode '(linefeed any any-one))) (define lf? (memq mode '(linefeed any any-one)))
(define crlf? (memq mode '(return-linefeed any))) (define crlf? (memq mode '(return-linefeed any)))
(let loop ([str (make-string 32)] [pos 0]) (let loop ([str (make-string 32)] [pos 0])
(define ch (read-char in)) (define ch (do-read-char 'read-line in))
(define (keep-char) (define (keep-char)
(if (pos . < . (string-length str)) (if (pos . fx< . (string-length str))
(begin (begin
(string-set! str pos ch) (string-set! str pos ch)
(loop str (add1 pos))) (loop str (add1 pos)))
(let ([new-str (make-string (* (string-length str) 2))]) (let ([new-str (make-string (fx* (string-length str) 2))])
(string-copy! new-str 0 str 0) (string-copy! new-str 0 str 0)
(string-set! new-str pos ch) (string-set! new-str pos ch)
(loop new-str (add1 pos))))) (loop new-str (add1 pos)))))
@ -46,7 +48,7 @@
(cond (cond
[(and crlf? [(and crlf?
(eqv? (peek-char in) (as-char #\linefeed))) (eqv? (peek-char in) (as-char #\linefeed)))
(read-char in) (do-read-char 'read-line in)
(substring str 0 pos)] (substring str 0 pos)]
[cr? [cr?
(substring str 0 pos)] (substring str 0 pos)]
@ -59,11 +61,11 @@
(define-read-line read-line (define-read-line read-line
make-string string-length string-set! make-string string-length string-set!
string-copy! substring string-copy! substring
read-char peek-char do-read-char/core-port peek-char
values) values)
(define-read-line read-bytes-line (define-read-line read-bytes-line
make-bytes bytes-length bytes-set! make-bytes bytes-length bytes-set!
bytes-copy! subbytes bytes-copy! subbytes
read-byte peek-byte do-read-byte/core-port peek-byte
char->integer) char->integer)

View File

@ -21,6 +21,7 @@
peek-string! peek-string!
do-read-char do-read-char
do-read-char/core-port
do-peek-char) do-peek-char)
;; ---------------------------------------- ;; ----------------------------------------
@ -265,8 +266,10 @@
;; If `special-ok?`, can return a special-value procedure ;; If `special-ok?`, can return a special-value procedure
(define (do-read-char who in #:special-ok? [special-ok? #f]) (define (do-read-char who in #:special-ok? [special-ok? #f])
(check who input-port? in)
(let ([in (->core-input-port in)]) (let ([in (->core-input-port in)])
(do-read-char/core-port who in #:special-ok? special-ok?)))
(define (do-read-char/core-port who in #:special-ok? [special-ok? #f])
(define read-byte (core-input-port-read-byte in)) (define read-byte (core-input-port-read-byte in))
(cond (cond
[(not read-byte) [(not read-byte)
@ -277,7 +280,7 @@
v)] v)]
[else [else
;; Byte-level shortcut is available, so try it as a char shortcut ;; Byte-level shortcut is available, so try it as a char shortcut
(read-char-via-read-byte who in read-byte #:special-ok? special-ok?)]))) (read-char-via-read-byte who in read-byte #:special-ok? special-ok?)]))
(define/who (read-char [in (current-input-port)]) (define/who (read-char [in (current-input-port)])
(check who input-port? in) (check who input-port? in)