In-memory stream performance on word data

Joshua 'Schwa' Gargus schwa at cc.gatech.edu
Sun Aug 24 03:31:03 UTC 2003


On Sat, Aug 23, 2003 at 12:44:30PM +0200, Boris Gaertner wrote:
> Joshua 'Schwa' Gargus <schwa at cc.gatech.edu> wrote:
> 
> Hi Joshua,
> you wrote:
> >
> > I am using ReferenceStream to serialize some objects, the bulk of
> > whose memory usage is in the form of B3DRotationArrays and
> > B3DMatrix4x4Arrays (implemented exactly as B3DRotationArray, except
> > the class-side method #contentsClass answers B3DMatrix4x4).
> >
> > I am using a ReferenceStream on top of a RWBinaryOrTextStream.  This
> > is so I can create a ZipArchive containing several serialized objects
> > without having to write a temporary file to disk, and then add it to
> > the archive.
> >
> > I have found that the performance is much worse when the
> > ReferenceStream is on top of an RWBinaryOrTextStream instead of a
> > StandardFileStream (by a factor of about 20).  This appears to be
> > because StandardFileStream uses a BitBlt-based hack to improve
> > performance in #nextWordsPutAll:, while RBBinaryOrTextStream defaults
> > to the implementation in Stream.
> I think that StandardFileStream is fast because it has a very efficient
> inplementation for  nextPutAll:. The method Stream>>nextPutAll:, which
> is inherited by most subclasses, copies the elements of its argument
> one by one which is not a very efficient solution. (See more about
> this below [proposal2])
> >
> > My questions are:
> >
> > 1) Is there any reason why the StandardFileStream implementation shouldn't
> > be used in RWBinaryOrTextStream, or even in Stream?
> >
> > 2) I tried doing #1, and ran into trouble because my new
> > implementation of #nextWordsPutAll: calls
> RWBinaryOrTextStream>>nextPutAll:,
> > which sends #asString to the byte-swapped B3DRotationArray copy, which
> > doesn't do anything sensible at all.  Instead of cloning the
> > B3DRotationArray, could I copy its bits into a ByteArray before
> > swapping bytes?  What is the easiest way to copy word data into a
> > ByteArray?
> >
> The buffer of RWBinaryOrTextStream is *always* a string - even when the
> instance variable  isBinary contains the value  true. I conclude that a
> local implementation of  RWBinaryOrTextStream>>nextWordPutAll:
> has to call  #nextPutAll:  with a string-valued argument.
> The attached file  proposal1.cs  contains a local implementation of
> nextWordPutAll:  and auxiliary definitions in B3DInplaceArray
> and WordArray.  You see that I convert the B3DRotationArray
> first into a WordArray, then into a ByteArray (this is the conversion
> that handles the endianess issue) and finally into a String.

proposal1.cs breaks on the following example (it works if the axis is set
to 1 at 1@1 instead):

rotations := B3DRotationArray new: 100 withAll: (B3DRotation angle: 45 axis: -1 at 1@1).
binStream := RWBinaryOrTextStream on: ''.
binStream binary.
refStream := ReferenceStream on: binStream.
refStream nextPut: rotations.
refStream close.


I get your general drift, though.  I think that a combination of your
approach and Yoshiki's would probably be best.  The BitBlt hack should
work on any object that contains words without it having to define
#asWordArray.

I like the idea of proposal2.cs, although growing so that the free
space is some multiple of the total collection size might be even
better than hardwiring in 10 bytes of extra space.

Thanks for your help.  I'll do the timings once I get a variant of
proposal1 working with the BitBlt hack.

Joshua


> 
> RWBinaryOrTextStream  has a lot of users, I am not sure that this
> change will not create problems elsewhere. Such problems can be
> caused by missing definitions of method  asWordArray.
> 
> Now a word about WriteStream>> nextPutAll:
> 
> You message clearly says that you need speed. I think that it is
> possible to speed up  WriteStream>nextPutAll: This method iterates
> over the argument collection when it has to grow the collection it
> writes to. The use of a grow function is the better solution
> because it allows the use of  the very fast
> String>>replaceFrom:to:with:startingAt:
> 
> The file  proposal2.cs  contains this change.
> 
> Your message indicates that you have code to message execution times
> with an example of realistic size. Given that this is true, I would like
> to ask you measure execution times first
>  -> with proposal1.cs  only
> and then
>  -> with proposal1.cs and proposal2.cs together.
> I expect that the changes in  proposal2.cs  do a lot to speed up
> your application.
> 
> Hope this helps. If it does not work, please do not hesitate to
> tell me where the problems are.
> 
> Greetings, Boris



> 



More information about the Squeak-dev mailing list