On 08 Dec 2010, at 00:25, Levente Uzonyi wrote:

>> Thanks for the explanation, some quick and dirty buffering makes a huge 
>> difference:
>> 
>> [ FileStream fileNamed: '/tmp/numbers.txt' do: [ :fileStream |
>>      1000 timesRepeat: [
>>              fileStream nextPutAll:
>>                      (String streamContents: [ :stream |
>>                              100 timesRepeat: [ stream print: 100 atRandom; 
>> space ] ]) ] ] ] timeToRun.
>> 159
>> 
>> Still, the asymmetry is a bit strange.
>> Can't the side effects be dealt with using #flush ?
> 
> Lets go back in time. A year ago there was no read buffering (Pharo 1.0 was 
> not released, Squeak 3.10.2 was out) and reading from a file was as slow as 
> writing is currently. Read buffering could be added transparently, so it 
> could give a huge speed improvement to all existing code.
> Write buffering could be done the same way, but it would break code, because 
> currently a write is immediately done, while with buffering it
> wouldn't be. Some files would be written only when the finalization process 
> closes the file. The solution for this could be automatic flushing on each 
> write, which could be turned off by a method. But that would be the same as 
> not using write buffering at all.
> But with the same effort you could use another stream implementation, that 
> does write buffering. And write buffering can't be used to speed up existing 
> code without reviewing it.

Thanks again for the explanation.

OK, I tried writing my own buffered write stream class:

[ FileStream fileNamed: '/tmp/numbers.txt' do: [ :fileStream | | bufferedStream 
|
        bufferedStream := ZnBufferedWriteStream on: fileStream.
        100000 timesRepeat: [ bufferedStream print: 100 atRandom; space ].
        bufferedStream flush ] ] timeToRun.
165

That wasn' too hard. And indeed, it is necessary to manually send #flush or 
#close to force the buffer out.

But I do not completely agree with the fact that it would be that much work. 
Stream>>#flush is already a no-op. Adding it to #streamContents: and some 
others can not be that much work. In fact, SocketStream does already do both 
input and output buffering (and thus requires #flush or #close), so would 
potentially fail in certain situations according to your reasoning. No ?

Sven


Reply via email to