[squeak-dev] CustomHelpToOrg dev question.
Levente Uzonyi
leves at caesar.elte.hu
Fri Sep 3 21:38:40 UTC 2021
Hi Chris,
On Fri, 3 Sep 2021, Chris Muller wrote:
> Hi Levente,
>
> An easy way to avoid that would be to write directly into the file stream,
> but Squeak's file streams are not write-buffered
>
>
> Hm, I always thought they were. A quick script I used to verify:
>
> | ws rs |
> nil assert: (FileDirectory default fileExists: 'writebuffered') not.
> FileDirectory default deleteFileNamed: 'writebuffered'.
> [ws := FileStream fileNamed: 'writebuffered'.
> rs := FileStream readOnlyFileNamed: 'writebuffered'.
> ws nextPutAll: '12345678901'.
> "Assert only buffered, not written"
> nil assert: (rs next: 10) isEmpty.
> "Force physical write"
> ws flush.
> "Assert written"
> nil assert: (rs next: 10) = '1234567890' ] ensure:
> [ ws ifNotNil: [ws close].
> rs ifNotNil: [rs close] ]
What I meant was actual write buffering at the image level.
Without that, each write operation (e.g. #nextPut:) will invoke a
primitive to write the contents to the file.
Here's an example which also demonstrates the effect of read buffering as
a reference:
| filename n |
filename := UUID new asString36.
n := 1000000.
[ {
StandardFileStream newFileNamed: filename do: [ :file |
[ n timesRepeat: [ file nextPut: $x ] ] timeToRun ].
StandardFileStream forceNewFileNamed: filename do: [ :file |
[ n timesRepeat: [ file nextPutAll: 'x' ] ] timeToRun ].
StandardFileStream forceNewFileNamed: filename do: [ :file |
[ file nextPutAll: (String new: n streamContents: [ :s |
n timesRepeat: [ s nextPut: $x ] ]) ] timeToRun ].
StandardFileStream forceNewFileNamed: filename do: [ :file |
[ file nextPutAll: (String new: n withAll: $x) ] timeToRun ].
StandardFileStream readOnlyFileNamed: filename do: [ :file |
[ n timesRepeat: [ file next ] ] timeToRun ].
StandardFileStream readOnlyFileNamed: filename do: [ :file |
file disableReadBuffering.
[ n timesRepeat: [ file next ] ] timeToRun ].
StandardFileStream readOnlyFileNamed: filename do: [ :file |
[ file next: n ] timeToRun ].} ]
ensure: [ FileDirectory default deleteFileNamed: filename ]
"==> #(137 116 16 1 20 135 1)"
The first two blocks write directly to the file, one character a time with
#nextPut: and #nextPutAll:, respectively.
The third one writes to an in-memory stream first, one character a time,
then writes the whole string in a single operation to the file.
The fourth one is the same as the third but creates the string directly
without streaming the characters one-by-one.
The fifth block reads back the file, one character a time using read
buffering which is enabled by default.
The sixth block does the same but without read buffering.
The seventh block reads the contents of the file in a single read
operation.
Levente
More information about the Squeak-dev
mailing list
|