Строка чтения Chicken Scheme занимает слишком много времени - PullRequest
0 голосов
/ 10 июля 2020

Есть ли быстрый способ прочитать и разметить большой корпус? Я пытаюсь прочитать текстовый файл среднего размера, и скомпилированный CHICKEN, кажется, просто зависает (я убил процесс примерно через 2 минуты), тогда как, скажем, Racket работает приемлемо (около 20 сек c). Могу ли я что-нибудь сделать, чтобы добиться такой же производительности на КУРИЦЕ? Это код, который я использую для чтения файла. Все предложения приветствуются.

(define *corpus*
  (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))))))))

Ответы [ 2 ]

1 голос
/ 10 июля 2020

Попробуйте запустить его с большей начальной кучей:

./prog -:hi100M

Программа выполняет много распределений, что означает, что размер кучи необходимо сильно изменить, что вызывает много основных сборщиков мусора (а они дорогие).

Вы можете увидеть, как изменяется размер кучи, когда вы включаете отладочный вывод:

./prog -:d

Если вы хотите увидеть G C вывод, попробуйте:

./prog -:g

0 голосов
/ 02 августа 2020

В случае, если вы можете позволить себе прочитать весь файл в память за один 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.

...