At Thu, 24 Jul 2014 09:27:42 +0100, Antonio Menezes Leitao wrote: > Hi, > > While trying to benchmark some of my code, I tried to minimize the time > spend on predefined IO functions, such as write-byte & friends, by using > the port returned by open-output-nowhere, expecting that it would be faster > than using, e.g., open-output-bytes, which has to accumulate the output. > > However, contrary to my expectations, it turns out that using > open-output-nowhere is 10 times slower that using open-output-bytes. > > Here is one example: > > #lang racket > (define (test i n p) > (time (for ([l (in-range n)]) > (write-byte i p)))) > > (test 123 100000000 (open-output-bytes)) > (test 123 100000000 (open-output-nowhere)) > > I'm getting: > > cpu time: 2860 real time: 2854 gc time: 32 > cpu time: 28906 real time: 28904 gc time: 125 > > What's causing this difference?
Byte-string output ports are built into the run-time system, while `open-output-nowhere` is implemented with `make-output-port`. The run-time system does a lot of work to protect itself from output ports constructed by `make-output-port` that might be misbehaved, so that's why it's is slower. Meanwhile, the path to write a single byte to a byte-string port is streamlined within the run-time system. I've considered building `open-output-nowhere` into the run-time system, but I think we're more likely to go the other direction: re-implement the port layer in Racket with a simpler and smaller interface from the run-time system. Out of curiosity, does this difference in performance show up in your application? Writing a single byte at a time in blocking mode is the worst-case scenario for comparing byte-string ports versus ports constructed with `make-output-port`. Still, given the speed for writing 100 million individual bytes even for `open-output-nowhere`, I would expect a typical application driving that work to take a lot more time. ____________________ Racket Users list: http://lists.racket-lang.org/users

