Проблема не в том, что MIT-Scheme такая медленная. Проблема в том, что вы чрезмерно вызываете функцию ядра write
. Ваша программа переключается для каждого символа из пользовательского режима в режим ядра. На это уходит много времени. Если вы сделаете то же самое в Bash, это займет еще больше времени.
Ваша версия схемы:
(define (write-stuff port)
(define (loop cnt)
(if (> cnt 0)
(begin (display "0" port)
(loop (- cnt 1)))))
(loop 10000000))
(call-with-output-file "mit-scheme-tmp.txt" write-stuff)
(exit)
Обертка для запуска версии схемы:
#! /bin/bash
mit-scheme --quiet --load mit-scheme-implementation.scm
В моей системе это занимает около 1 минуты:
$ time ./mit-scheme-implementation
real 1m3,981s
user 1m2,558s
sys 0m0,740s
То же самое для Bash:
#! /bin/bash
: > bash-tmp.txt
n=10000000
while ((n > 0)); do
echo -n 0 >> bash-tmp.txt
n=$((n - 1))
done
занимает 2 минуты:
$ time ./bash-implementation
real 2m25,963s
user 1m33,704s
sys 0m50,750s
Решение : не выполнять 10 миллионов переключений режима ядра.
Выполнять только один (или, по крайней мере, в 4096 раз меньше):
(define (write-stuff port)
(display (make-string 10000000 #\0) port))
(call-with-output-file "mit-scheme-2-tmp.txt" write-stuff)
(exit)
И программе требуется всего 11 секунд.
$ time ./mit-scheme-implementation-2
real 0m11,390s
user 0m11,270s
sys 0m0,096s
Вот почему в библиотеке C была изобретена буферизация: https://www.gnu.org/software/libc/manual/html_node/Stream-Buffering.html#Stream -Buffering