[squeak-dev] 20X speedup for read file upToEnd

Levente Uzonyi leves at caesar.elte.hu
Sat Jan 23 19:58:07 UTC 2021

Hi Dave,

Good catch. That method of StandardFileStream, unlike #upTo: and 
#upToAnyOf:do:, has not been optimized.

IMO, StandardFileStream >> #upToEnd should simply be

 	^self next: self size - self position

And I suggest your implementation be added to MultiByteFileStream with the 
following modifications:

 	"Answer a subcollection from the current access position through the last element of the receiver."

 	| remainingEstimate |
 	self isBinary ifTrue: [ ^super upToEnd ].
 	remainingEstimate := self size - self position.
 	^self collectionSpecies
 		new: remainingEstimate
 		streamContents: [ :stream |
 			| elements chunkSize |
 			chunkSize := remainingEstimate min: 2000. "It's not worth allocating larger chunks"
 			[ (elements := self next: chunkSize) isEmpty ] whileFalse: [
 				stream nextPutAll: elements ] ]


On Fri, 22 Jan 2021, David T. Lewis wrote:

> Attached is a small change that gives a big performance boost for reading
> a file upToEnd. My use case (where I noticed this) is reading an image
> file, where the file is opened, the header is read, and the remainder of
> the file upToEnd is read in as the object memory:
>  fs := FileStream readOnlyFileNamed: Smalltalk imageName. fs binary.
>  t := Time millisecondsToRun: [ImageSnapshot fromStream: fs].
>  fs close.
>  t
>  ==> 12428 "original implementation"
>  ==> 645 "new version"
> Overall speedup is about 20X for MultiByteFileStream and over 100x for
> StandardFileStream (difference due to Levente's earlier improvements
> in MultiByteFileStream).
> This small change touches two packages so I'm posting it as a change set
> for comment. I'll put it in trunk if there are no issues.
> Dave

More information about the Squeak-dev mailing list