perf: elf read-c-string bulk NUL scan + preallocated string (was per-byte u8 + reversed char list)
ober
ae785f25c546f6870a0f7a6f725f59ccbb603158
--- a/lib/jasm/object/elf.ss +++ b/lib/jasm/object/elf.ss @@ -203,14 +203,22 @@ (define (read-c-string bv offset limit) (require-range 'read-elf-bytevector bv offset 0) - (let loop ([i offset] [chars '()]) - (cond - [(or (>= i limit) (>= i (bv-len bv))) - (list->string (reverse chars))] - [(zero? (u8 bv i)) - (list->string (reverse chars))] - [else - (loop (+ i 1) (cons (integer->char (u8 bv i)) chars))]))) + ;; Scan for the NUL terminator with direct byte refs (one range check up + ;; front, not one per byte) and fill a preallocated string instead of + ;; consing a reversed char list. + (let ([end (min limit (bv-len bv))]) + (let scan ([i offset]) + (if (or (>= i end) (zero? (bytevector-u8-ref bv i))) + (let* ([len (- i offset)] + [s (make-string len)]) + (let fill ([j 0]) + (if (= j len) + s + (begin + (string-set! s j + (integer->char (bytevector-u8-ref bv (+ offset j)))) + (fill (+ j 1)))))) + (scan (+ i 1)))))) (define (raw-section-header class endian bv offset) (if (eq? class 'elf64)