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

David T. Lewis lewis at mail.msen.com
Fri Jan 22 23:24:08 UTC 2021

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.
  ==> 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.


-------------- next part --------------
'From Squeak6.0alpha of 19 January 2021 [latest update: #20168] on 22 January 2021 at 5:47:20 pm'!
"Change Set:		Speedup-file-upToEnd-dtl
Date:			22 January 2021
Author:			David T Lewis

Make MultiByteFileStream>>upToEnd faster by reading 1000 at a time rather than calling a primitive once per byte. Move this method up to StandardFileStream to avoid duplication. MulitbyteFileStream was already much faster due to better buffer allocation, this improves it by reducing trips to the VM for each byte read. Overall improvement is close to 20x faster."!

!StandardFileStream methodsFor: 'read, write, position' stamp: 'dtl 1/22/2021 17:37'!
	"Answer a subcollection from the current access position through the last element of the receiver."

	^self collectionSpecies
		new: self size - self position
		streamContents: [ :stream |
			| elements |
			[ (elements := self next: 1000) isEmpty ] whileFalse: [
				stream nextPutAll: elements ] ]
! !

MultiByteFileStream removeSelector: #upToEnd!

More information about the Squeak-dev mailing list