[racket-dev] read-line performance problem

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Thu Nov 3 11:26:48 EDT 2011

At Wed, 02 Nov 2011 20:54:25 -0400, Neil Van Dyke wrote:
> Racket can do this somewhat faster, but I suggest any effort be focused 
> on improvements that are also relevant to substantial programs, and not 
> on trying to compete on Perl one-liners and poor benchmarks.

Agreed, but in this case, I think the example acts as microbenchmark to
expose a generally slow `read-byte', and that could be worth improving.

The `read-byte' function was slow because so much is built into the
Racket port system --- non-character values, events, peeking,
line-counting, and more --- that there can be a lot of overhead to get
a single byte at a time.

I've looked into the problem before, but I made more progress this time
with a fresh look. An input port now has an internal flag that
indicates whether anything complicated is enabled on the port; if not,
a lightweight `read-byte' dispatch can be inlined.

With that and related changes, the example now runs about 3 times as
fast as before on my machine (or about 2 times as fast for
`read-bytes-line') on an 73-MB input containing 72-byte ASCII lines
using a 64-bit build. There's certainly still room for improvement, as
the Racket code is about 50% slower than the Chicken code (instead of a
small-integer factor slower), but that's enough for today.

The change provides a minor benefit to at least one real program: The
3m transformation of "portfun.c" now runs about 10% faster. (I would
not have thought of that program as an example, but when I broke
`read-byte' while trying to improve it, I couldn't build Racket 3m.)

Posted on the dev mailing list.