Tanaka Akira wrote:
> I guess the timeout() is slow.
>
> Try:
>
>     def rbuf_fill
>       @rbuf << @io.sysread(1024)
>     end
>   
The main problem seems to be, that the read* methods of BufferedIO all 
suffer from the small value in rbuf_fill. If I download a big file it's 
very likely, that TCP packets are bigger than 1024 bytes (depending on 
my network infrastructure). For every received packet I have to call 
lots of Ruby methods to handle it. At the same time this renders 
operation system buffers, that are usually higher than 1024 bytes 
useless. This is a big overhead per packet, which reduces the maximum 
bandwidth, that can be achieved.
> However, the above is not acceptable in general since
> timeout is a feature.
>
> It is possible to implement timeout without timeout() as:
>
>     def rbuf_fill
>       begin
>         @rbuf << @io.read_nonblock(4096)
>       rescue Errno::EWOULDBLOCK
>         if IO.select([@io], nil, nil, @read_timeout)
>           @rbuf << @io.read_nonblock(4096)
>         else
>           raise Timeout::TimeoutError
>         end
>       end
>     end
>   
This would be even faster I think, because timeout also represents a lot 
of overhead. For 1.8. those methods would have to be backported then. 
Hint, hint... ;)

-- 
Florian Frank