stream interfaces - with ranges
Steven Schveighoffer
schveiguy at yahoo.com
Fri May 18 06:27:32 PDT 2012
On Fri, 18 May 2012 00:19:45 -0400, kenji hara <k.hara.pg at gmail.com> wrote:
> I think range interface is not useful for *efficient* IO. The expected
> IO interface will be more *abstract* than range primitives.
If all you are doing is consuming data and processing it, range interface
is efficient. Most streaming implementations that are synchronous use:
1. read block of data from low-level source into buffer
2. process buffer
3. If still data left, go to step 1.
1 is done via popFront, 2 is done via front.
3 is somewhat available via empty, but empty kind of depends on reading
data. I think it can work.
It's not the ideal interface for all aspects of i/o, but it does map to
ranges, and for single purpose tasks (such as parse an XML file), it will
be most efficient.
> ---
> If you use range I/F to read bytes from device, we will always do
> blocking IO - even if the device is socket. It is not efficient.
>
> auto sock = new TcpSocketDevice();
> if (sock.empty) { auto e = sock.front; }
> // In empty primitive, we *must* wait the socket gets one or more
> bytes or really disconnected.
> // If not, what exactly returns sock.front?
> // Then using range interface for socket reading enforces blocking
> IO. It is *really* inefficient.
> ---
sockets do not have to be blocking, and I/O does not have to use the range
portion of the interface.
And efficient I/O has little to do with synchronicity and more to do with
reading a large amount of data at a time instead of byte by byte.
Using multi-threads or fibers, and using OS primitives such as select or
poll can make I/O quite efficient and allow you to do other things while
no I/O is happening. These will not happen with range interface, but will
be available through other interfaces.
> I think IO primitives must be distinct from range ones for the reasons
> mentioned above...
Yes, I agree. But ranges can be *mapped* to stream primitives.
> I'm designing experimental IO primitives:
> https://github.com/9rnsr/dio
I'll take a look.
>
> In other words, range is not almighty. We should think distinct
> primitives for the IO.
100% agree. The main thing I realized that brought me to propose the
"range-based" (if you can call it that) version is that:
1. Ranges can be readily mapped to stream primitives *if* you use the
concept of a range of T[] vs. a range of T. So in essence, without
changing anything I can slap on a range interface for free.
2. Arrays make very efficient data sources, and are easy to create. We
need a way to hook stream-using code onto an array.
But be clear, I am *not* going to remove the existing stream I/O
primitives I had for buffered i/o, I'm rather *adding* range primitives as
well.
-Steve
More information about the Digitalmars-d
mailing list