[Pharo-project] Basic tricks for improving a serializer?
siguctua at gmail.com
Wed May 18 00:16:12 CEST 2011
On 17 May 2011 22:58, Mariano Martinez Peck <marianopeck at gmail.com> wrote:
> On Tue, May 17, 2011 at 10:31 PM, Sven Van Caekenberghe <sven at beta9.be>
>> On 17 May 2011, at 21:57, Mariano Martinez Peck wrote:
>> > Sven, I want to make it work :)
>> > so....the missing methods I told you that I need are:
>> > #nextStringPut:
>> > #nextNumber:put:
>> > #nextInt32Put:
>> > #nextWordPut:
>> I guess these are pretty easy. But I think they clutter the interface of
>> ZnBufferedWriteStream, so maybe you should make a subclass.
> Yeah, don't worry. I can even duplicate the class hehehe
>> > #contents
>> > Implement #contents I guess it is something like:
>> > ZnBufferedWriteStream >> contents
>> > ^ stream contents
>> Why to you need #contents ?
> becasue I am an idiot. No, I don't need it. You are correct. Thanks for
>> I would say that it goes a bit against the concept of a stream as a sink
>> of data.
>> I haven't looked, but I would guess that saying #contents to a FileStream
>> is not efficient.
>> > Those missing methods I need are implemented PositionableStream. I took
>> > the implementation from there and put it in ZnBufferedWriteStream.
>> > I just added to them a first line " self flushBufferIfFull."
>> That is probably OK, except when your string becomes larger than the
>> buffer. Have a look at #nextPutAll:
> I am not sure if I understood. The following are correct for sure then:
> And #nextStringPut: is like this:
> nextStringPut: s
> "Append the string, s, to the receiver. Only used by DataStream. Max
> size of 64*256*256*256."
> | length |
> self flushBufferIfFull.
> (length := s size) < 192
> ifTrue: [self nextPut: length]
> [self nextPut: (length digitAt: 4)+192.
> self nextPut: (length digitAt: 3).
> self nextPut: (length digitAt: 2).
> self nextPut: (length digitAt: 1)].
> self nextPutAll: s asByteArray.
Sorry, but i can't resist commenting on that.
Why, if you demand from stream to implement #nextInt32Put:
a the same time, you writing code like this
self nextPut: (length digitAt: 4)+192.
self nextPut: (length digitAt: 3).
self nextPut: (length digitAt: 2).
self nextPut: (length digitAt: 1)
Then just extend your serializer with a notion of 'length' field,
which you can use for anything where you need to encode length/size value,
but not just for Strings.
So, then the above method could be as short as:
self putLength: s size.
self nexPutAll: s asByteArray.
and here you have a potential caveat because your string could be
WideString .. muhahaha.
So, i suggest you to reconsider the way how you serializing strings.
Instead what you could do is to extend ByteString and WideString (and
perhaps similarily do for ByteSymbol and WideSymbol),
the methods which is responsible to turning a receiver in a sequence
of bytes, and then simply put it into output stream,
whatever it might be.
Then you don't need #nextStringPut: because its
a) not polymorphic, because apparently serializing ByteString should
be different from serializing WideString
b) instead you implementing this in
Byte/WideString>>serializeToFuelStream: aStream and you done.
> which will finally send #nextPutAll: that does correct check.
>> > The way I am creating it is like this:
>> > stream := ZnBufferedWriteStream on: ((FileDirectory default
>> > forceNewFileNamed: 'mariano') binary).
>> > So...is this correct Sven? My tests are green :)
>> That seems OK
>> > Still need to try benchmarks.
>> You might also consider playing with making the buffer larger.
> yeah, I was trying that. Just by curious, why you put a 2^X number there?
> Ahh and for reading we don't need something special because it is already
> buffered? (I have been told that)
> Thanks a lot Sven,
Igor Stasenko AKA sig.
More information about the Pharo-project