[squeak-dev] Faster FileStream experiments

Igor Stasenko siguctua at gmail.com
Sat Nov 28 00:54:55 UTC 2009


2009/11/28 Eliot Miranda <eliot.miranda at gmail.com>:
>
>
> On Fri, Nov 27, 2009 at 4:40 PM, Igor Stasenko <siguctua at gmail.com> wrote:
>>
>> 2009/11/28 Nicolas Cellier <nicolas.cellier.aka.nice at gmail.com>:
>> > 2009/11/27 Eliot Miranda <eliot.miranda at gmail.com>:
>> >> An approach I like is to add an endOfStreamValue inst var to Stream and
>> >> answer its value when at end.  This way nil does not have to be the
>> >> endOfStreamValue, for example -1 might be much more convenient for a
>> >> binary
>> >> stream, and streams can answer nil without confusing their clients.
>> >>  atEnd
>> >> can be implemented as
>> >>     atEnd
>> >>         ^self peek = self endOfStreamValue
>> >> You can arrange to make streams raise an end-of-stream exception
>> >> instead of
>> >> the endOfStreamValue by using some convention on the contents of
>> >> endOfStreamValue, such as if it is == to the stream itself (although I
>> >> note
>> >> that in the Teleplace image the exception EndOfStrean is defined bit
>> >> not
>> >> used).
>> >>
>> >> Of course, stream primitives get in the way of adding inst vars to
>> >> stream
>> >> classes ;)
>> >> IMO this is a much more useful scheme than making nil the only
>> >> endOfStream
>> >> value.
>> >>
>> >
>> > Last time I proposed to have an inst var endOfStreamAction was here
>> >
>> > http://lists.gforge.inria.fr/pipermail/pharo-project/2009-June/009536.html
>> > .
>> > Abusing nil value -> nil, I could even let this inst var
>> > un-initialized and be backward compatible
>> > (initializing with a ValueHolder on nil would do as well)
>> >
>>
>> Nicolas, have you considered introducing methods which allow
>> graciously handle the end-of-stream while reading?
>> Something like:
>>
>> nextIfAtEnd: aBlock
>> and
>> next: number ifAtEnd: aBlock
>>
>>
>> then caller may choose to either write:
>>
>> char := stream nextIfAtEnd: [nil]
>>
>> or handle end of stream differently, like leaving the loop:
>>
>> char := stream nextIfAtEnd: [^ results]
>>
>> the benefit of such approach that code which reads the stream , don't
>> needs to additionally
>> test stream state (atEnd) in iteration between #next sends neither
>> requires some unique value (like nil) returned by #next
>> when reaching end of stream.
>
> IMO the block creation is too expensive for streams.  The defaultHandler
> approach for and EndOfStream exception is also too expensive.  The
> endOfStreamValue inst var is a nice trade-off between flexibility,
> efficiency and simplicity.  You can always write
>      [(value := stream next) ~~ stream endOfStreamValue] whileTrue:
>         [...do stuff...
>

hmm, can you elaborate, at what point you see an expensive block creation?
A block closure is created once at compiling stage, and then passed as
any other object by reading it
from literal frame of method (and as well as , you can use 'stream
nextIfAtEnd: nil' , right?). And only if its going to be activated (by
sending #value), a corresponding block context is created in order to
evaluate the block. But it happens only when you reaching the end of
stream.

It is more expensive because of passing extra argument, i.e. use
#nextIfAtEnd: instead of #next , but not because of passing block,
IMO.

>>
>> > Nicolas
>> >
>>
>>
>> --
>> Best regards,
>> Igor Stasenko AKA sig.
>>


-- 
Best regards,
Igor Stasenko AKA sig.



More information about the Squeak-dev mailing list