Marc:
macro-read-char is a fair amount of code to inline at each site of
read-char. We have with the original
-rw-r--r-- 1 lucier pfaculty 107585 Feb 10 12:47 bewig2.c
-rwxr-xr-x 1 lucier pfaculty 52001 Feb 10 12:47 bewig2.o1*
-rw-r--r-- 1 lucier pfaculty 10799 Feb 10 11:36 bewig2.scm
If we replace all 16 instances of read-char with macro-read-char, we get
-rw-r--r-- 1 lucier pfaculty 175125 Feb 10 13:38 bewig2+macro-read-
char.c
-rwxr-xr-x 1 lucier pfaculty 71575 Feb 10 13:38 bewig2+macro-read-
char.o2*
-rw-r--r-- 1 lucier pfaculty 10925 Feb 10 13:38 bewig2+macro-read-
char.scm
Part of the problem here is that, if function A calls function B,
Gambit's inlining heuristic looks at the size of the macro-expanded
function A before deciding whether to inline function B into A; if
macro-expansion increases the size of A a lot (say, by expanding
macro-read-char ;-), then B is more likely to be inlined into A.
This happened with two of the state-machine functions in read-csv-
record.
If, instead, we add a simple function my-read-char
(define (my-read-char port)
(macro-read-char port))
and then replace calls to read-char by calls to my-read-char, we get
-rw-r--r-- 1 lucier pfaculty 134833 Feb 11 11:50 bewig3.c
-rwxr-xr-x 1 lucier pfaculty 59349 Feb 11 11:50 bewig3.o1*
-rw-r--r-- 1 lucier pfaculty 10929 Feb 11 11:50 bewig3.scm
and the times are almost as good as when macro-read-char is inlined
at all call sites of read-char, 113ms on Philip's benchmark instead
of 111ms. Recall that the time for using read-char is 435ms, so
we're about four times as fast.
So perhaps you should add another compilation strategy---for files
that have calls to read-char (or to any functions that are big
enough, or have a big enough fast path, that you don't want to inline
them into each call site), put in a local function that has the code
for macro-read-char, and redirect calls to read-char to this local
function (under suitable circumstances, of course).
Brad