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. At Sat, 7 May 2016 16:48:11 -0700, Alexis King wrote: > 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 > > -- > 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 [email protected]. > To post to this group, send email to [email protected]. > To view this discussion on the web visit > https://groups.google.com/d/msgid/racket-dev/C19327E2-AF25-4861-AFA2-1D50A01638 > DC%40gmail.com. > For more options, visit https://groups.google.com/d/optout. -- 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 [email protected]. To post to this group, send email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-dev/5730b346.1116620a.73d6e.ffffd047SMTPIN_ADDED_MISSING%40gmr-mx.google.com. For more options, visit https://groups.google.com/d/optout.
