Performance of Racket in R7RS benchmarks

290 views
Skip to first unread message

Alexis King

unread,
May 7, 2016, 7:48:15 PM5/7/16
to Racket-Dev List
Hello,

I maintain the Racket r7rs package, which as far as I know, has not
gotten much use. Recently, however, someone has put together a set of
R7RS benchmarks and run it against various Scheme implementations,
including Racket, using my r7rs-lib package. The benchmarks themselves
are here:

https://www.nexoid.at/tmp/scheme-benchmark-r7rs.html

I’ve been working to fix any areas in which Racket’s speed is negatively
impacted by the code I’ve written, and I’ve fixed a few small issues.
However, there are definitely a few areas where the performance problems
live outside of my code, and Sam recommended I bring up at least one of
them here.

Specifically, the following program is fairly slow:

#lang racket/base

(define (catport in out)
(let ((x (read-char in)))
(unless (eof-object? x)
(write-char x out)
(catport in out))))

(define (go input-file output-file)
(when (file-exists? output-file)
(delete-file output-file))
(call-with-input-file
input-file
(lambda (in)
(call-with-output-file
output-file
(lambda (out)
(catport in out))))))

It is a very simple cat implementation the benchmarks themselves invoke
it on a file about 4.5MB in size, and it takes about 15 seconds. This is
comparable with some other Scheme implementations, but it’s thoroughly
beaten by Bigloo, Chez, and Larceny, which are all in the 1-3 second
range. Replacing read-char and write-char with read-byte and write-byte
brings the time down to about 11 seconds, but it doesn’t change things
significantly. Is there any simple way this could be improved, or is the
time I’m getting just intrinsic to Racket’s implementation of I/O?

Alexis

Robby Findler

unread,
May 7, 2016, 8:40:59 PM5/7/16
to Alexis King, Racket-Dev List
Can you use use copy-port?

Robby
--
You received this message because you are subscribed to the Google Groups "Racket Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to racket-dev+...@googlegroups.com.
To post to this group, send email to racke...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/racket-dev/C19327E2-AF25-4861-AFA2-1D50A01638DC%40gmail.com.
For more options, visit https://groups.google.com/d/optout.

Matthew Flatt

unread,
May 9, 2016, 11:56:54 AM5/9/16
to Alexis King, Racket-Dev List
Yes, the port abstraction offers at once too much (in terms of
synchronization primitives and byte counting) and too little (in terms
of a way to define a single-byte or single-char fast path) to make this
microbenchmark go super fast.

There are some easy targets for improvement in Racket's implementation,
on the order of 30% by avoiding unnecessary GC-cooperation work, but
making it much faster would require adding a buffering layer to where
the JIT can see it. You should be able to add that buffering to R7RS
ports if you want them to go faster on this microbenchmark.

As Robby notes, the functionality of `catport` is available
`racket/port` as `copy-port` --- and `copy-port` should be fast, since
it works with blocks of data in the way that any realistic `cat`
program would. But, of course, functionality is not the point of the
microbenchmark.
Reply all
Reply to author
Forward
0 new messages