<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Jul 24, 2014 at 10:04 AM, Matthew Flatt <span dir="ltr"><<a href="mailto:mflatt@cs.utah.edu" target="_blank">mflatt@cs.utah.edu</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class=""><div class="h5">At Thu, 24 Jul 2014 09:27:42 +0100, Antonio Menezes Leitao wrote:<br>
> Hi,<br>
><br>
> While trying to benchmark some of my code, I tried to minimize the time<br>
> spend on predefined IO functions, such as write-byte & friends, by using<br>
> the port returned by open-output-nowhere, expecting that it would be faster<br>
> than using, e.g., open-output-bytes, which has to accumulate the output.<br>
><br>
> However, contrary to my expectations, it turns out that using<br>
> open-output-nowhere is 10 times slower that using open-output-bytes.<br>
><br>
> Here is one example:<br>
><br>
> #lang racket<br>
> (define (test i n p)<br>
> (time (for ([l (in-range n)])<br>
> (write-byte i p))))<br>
><br>
> (test 123 100000000 (open-output-bytes))<br>
> (test 123 100000000 (open-output-nowhere))<br>
><br>
> I'm getting:<br>
><br>
> cpu time: 2860 real time: 2854 gc time: 32<br>
> cpu time: 28906 real time: 28904 gc time: 125<br>
><br>
> What's causing this difference?<br>
<br>
</div></div>Byte-string output ports are built into the run-time system, while<br>
`open-output-nowhere` is implemented with `make-output-port`. The<br>
run-time system does a lot of work to protect itself from output ports<br>
constructed by `make-output-port` that might be misbehaved, so that's<br>
why it's is slower. Meanwhile, the path to write a single byte to a<br>
byte-string port is streamlined within the run-time system.<br>
<br>
I've considered building `open-output-nowhere` into the run-time<br>
system, but I think we're more likely to go the other direction:<br>
re-implement the port layer in Racket with a simpler and smaller<br>
interface from the run-time system.<br></blockquote><div><br></div><div>Is it possible to do the second approach without degrading the current performance of byte-string output ports? If that's possible, I would definitely prefer that.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
Out of curiosity, does this difference in performance show up in your<br>
application? Writing a single byte at a time in blocking mode is the<br>
worst-case scenario for comparing byte-string ports versus ports<br>
constructed with `make-output-port`. Still, given the speed for writing<br>
100 million individual bytes even for `open-output-nowhere`, I would<br>
expect a typical application driving that work to take a lot more time.<br></blockquote><div><br></div><div>This is just a matter of expectations. I expected that an output port that does not write anything has a smaller impact on the performance than an output port that has to keep the output in a buffer.</div>
<div><br></div><div>In fact, my application does not need to use ports created by open-output-nowhere but for purposes of comparing the performance of two different approaches to a particular encoding scheme, I was trying to minimize the time spend in the output functions and I imagined that a simple way of doing that without messing with the code of the functions would be to use an output port that does not write anything. Moreover, this has the advantage that it does not run out of memory even if the benchmark runs for a very long time. This is what I expect, for example, from Common Lisp and, indeed, that's the case in the Common Lisp implementations that I use (allegro and sbcl).</div>
<div><br></div><div>Thanks for the explanation.</div><div><br></div><div>Best,</div><div>António.</div></div></div></div>