В случае, если вы можете позволить себе прочитать весь файл в память за один go, вы можете использовать что-то вроде следующего кода, который должен быть быстрее:
(let loop ((lines (with-input-from-file "largeish_file.txt"
read-lines)))
(if (null? lines)
'()
(append (string-split (car lines))
(loop (cdr lines)))))
Вот небольшой тестовый код:
(import (chicken io)
(chicken string))
;; Warm-up
(with-input-from-file "largeish_file.txt" read-lines)
(time
(with-output-to-file "a.out"
(lambda ()
(display
(call-with-input-file "largeish_file.txt"
(lambda (input-file)
(let loop ([line (read-line input-file)]
[tokens '()])
(if (eof-object? line)
tokens
(loop (read-line input-file)
(append tokens (string-split line)))))))))))
(time
(with-output-to-file "b.out"
(lambda ()
(display
(let loop ((lines (with-input-from-file "largeish_file.txt"
read-lines)))
(if (null? lines)
'()
(append (string-split (car lines))
(loop (cdr lines)))))))))
И вот результаты в моей системе:
$ csc bench.scm && ./bench
28.629s CPU time, 13.759s GC time (major), 68772/275 mutations (total/tracked), 4402/14196 GCs (major/minor), maximum live heap: 4.63 MiB
0.077s CPU time, 0.033s GC time (major), 68778/292 mutations (total/tracked), 10/356 GCs (major/minor), maximum live heap: 3.23 MiB
Просто убедитесь, что мы получили одинаковый результат из обоих фрагментов кода:
$ cmp a.out b.out && echo They contain the same data
They contain the same data
largeish_file.txt
был сгенерирован путем cat'ing файла системного журнала размером ~ 100 КБ до тех пор, пока он не получил ~ 10000 строк (упоминание этого, чтобы вы получили представление о профиле входного файла):
$ ls -l largeish_file.txt
-rw-r--r-- 1 mario mario 587340 Aug 2 11:55 largeish_file.txt
$ wc -l largeish_file.tx
5790 largeish_file.txt
Результаты, которые я получил с использованием CHICKEN 5.2.0 в системе Debian.