EndOfStream performance cost [was EndOfStream unused]

Paolo Bonzini bonzini at gnu.org
Fri Nov 9 09:30:57 UTC 2007

> - Most String processing loops use atEnd loop (upper level ReadStream
> does not use == nil trick, client code might however uses few).

I found only one that doesn't, in InflateStream>>#atEnd, using this code:

(CompiledMethod allInstances
   select: [ :m | | s |
      s := m getSource asString.
      ('*next*' match: s ) and: [
         ('*next == nil*' match: s )  or: [
         ('*next isNil'  match: s ) or: [
         '*next notNil' match: s ]]]])

Here is the source code:

	"Note: It is possible that we have a few bits left,
	representing just the EOB marker. To check for
	this we must force decompression of the next
	block if at end of data."
	super atEnd ifFalse:[^false]. "Primitive test"
	(position >= readLimit and:[state = StateNoMoreData])
	self next == nil ifTrue:[^true].
	position := position - 1.

and in this same class, we have:

	state = StateNoMoreData ifTrue:[^nil].
	^self next

	<primitive: 65>
	position >= readLimit
		ifTrue: [^self pastEndRead]
		ifFalse: [^collection at: (position := position + 1)]

So, the "self next == nil" could be written "self pastEndRead == nil". 
Or even better, one could simply rewrite "atEnd and next" like this:

	position < readLimit ifFalse: [^false].
	"for speed, we inline pastEndRead with these changes:"
	state = StateNoMoreData ifTrue:[^true].

	<primitive: 65>
	"position >= readLimit test inlined for speed"
	(position >= readLimit and: [self atEnd]) ifTrue: [ ^nil ].
	^collection at: (position := position + 1)

Actually, this implementation of #next could be moved up to ReadStream, 
so that no override is necessary in InflateStream.  So, it looks like 
the only explicit usage (in my image) of "self next == nil" ought to be 
eliminated anyway.

In some cases, the "self next == nil" test is used implicitly, for example:

	('edq' includes: aStream next) ifFalse: [^ nil].

This code however does not seem to be written with speed in mind.


More information about the Squeak-dev mailing list