[squeak-dev] Object>>is:

Levente Uzonyi leves at elte.hu
Fri Feb 11 14:06:21 UTC 2011


On Thu, 10 Feb 2011, David T. Lewis wrote:

> On Fri, Feb 11, 2011 at 02:51:26AM +0100, Levente Uzonyi wrote:
>> On Fri, 11 Feb 2011, Igor Stasenko wrote:
>>
>>> On 11 February 2011 02:28, David T. Lewis <lewis at mail.msen.com> wrote:
>>>> We had a good deal of discussion earlier about adding Object>>is:
>>>> with an inconclusive outcome:
>>>> ?http://lists.squeakfoundation.org/pipermail/squeak-dev/2010-April/148501.html
>>>>
>>>> Igor's original proposal is:
>>>> ?http://lists.squeakfoundation.org/pipermail/squeak-dev/2009-June/136793.html
>>>>
>>>> I have been tinkering around with Juan's SimpleMorphic in hopes of
>>>> getting it running in Squeak alongside MVC and Morphic, and it would
>>>> be convenient to have the default implementation of #is: in the image
>>>> so I don't have to put it in a package override.
>>>>
>>>
>>> Just yesterday i had  discussion about this with people in the lab. I
>>> can't say that i heard something new regarding this,
>>> and not saying that i'd like to resurrect the discussion.
>>> So, in short: there was no objection concerning getting rid of isXXX
>>> in favor of using #is: method.
>>
>> What about performance?
>
> I do not think that Juan would have chosen to use the #is: idiom for
> his Cuis Morphic implementation if he thought that performance would
> be a problem. It seems to work well.

You're right, it's pretty fast, but methods that return only a boolean 
and have no arguments are special methods, which is true for almost every 
#is* methods. I did a quick benchmark to see the effects of the change:

Object
 	compile: 'is: aSymbol

 		^false'
 	classified: 'testing'.
Morph
 	compile: 'is: aSymbol

 		^aSymbol == #Morph or: [ super is: aSymbol ]'
 	classified: 'testing'.
{
 	[
 		Smalltalk garbageCollect.
 		(1 to: 5) collect: [ :run |
 			[ SystemNavigation default allObjectsDo: [ :each | ] ] timeToRun ] ].
 	[
 		Smalltalk garbageCollect.
 		(1 to: 5) collect: [ :run |
 			[ SystemNavigation default allObjectsDo: [ :each | each isMorph ] ] timeToRun ] ].
 	[
 		Smalltalk garbageCollect.
 		(1 to: 5) collect: [ :run |
 			[ SystemNavigation default allObjectsDo: [ :each | each is: #Morph ] ] timeToRun ] ] }
 	collect: [ :each | each value ].

With SqueakVM (4.0.3 windows VM), I got the following results:
  #(#(43 44 45 44 44) #(53 53 54 53 54) #(64 64 64 64 64)).
So using #is: #Morph instead of #isMorph is 2.13x slower in this case.

With CogVM (r2361 on windows), I got these (after a few runs that ensure 
that Cog compiles the code to machine code):
  #(#(16 17 16 16 16) #(20 14 27 19 20) #(27 20 21 20 20))
So using #is: #Morph instead of #isMorph is 1.42x slower in this case.

I calculated the speedup with the following method (replace the array to 
the other case's to get the other result):

#(#(16 17 16 16 16) #(20 14 27 19 20) #(27 20 21 20 20))in: [ :results |
 	(results third average - results first average / (results second average - results first average)) asFloat ].

The difference for Cog is not significant, maybe just noise, but it's 
clear that using #is: is slower with SqueakVM.

Let's see a bit larger scale benchmark: SmalltalkImage >> 
#cleanUpUndoCommands. Note that this method is a "heavy user" of #is*.

(1 to: 5) collect: [ :run |
 	Smalltalk garbageCollect.
 	[ Smalltalk cleanUpUndoCommands ] timeToRun ].

With SqueakVM:
#isMorph : #(68 68 69 68 68)
#is: #Morph : #(83 83 90 82 83)

The difference is still there, but obviously smaller.

With CogVM (I couldn't force it to compile the method to machine code):
#isMorph : #(101 101 103 103 103)
#is: #Morph : #(103 102 103 103 104)

No real difference.

So code that uses #is* methods in tight loops may be slower with SqueakVM, 
but probably won't with CogVM. The change probably won't have measurable 
effect on other code.

>
>>
>>> The only thing which still looks controversial is too simple default
>>> implementation which answers false.
>>>
>>> To my current opinion, Juan's variant is preferable. :) Yes. it should
>>> answer false and don't contain any extra logic , like trying to follow
>>> class hierarchy etc.
>
> My intention is to include the method copied directly from Cuis, which is:
>
> is: aSymbol
> 	"A means for cleanly replacing all isXXX like methods.
> 	Please use judiciously!
> 	Suggested by Igor Stasenko at
> 	http://lists.squeakfoundation.org/pipermail/squeak-dev/2009-June/136793.html"
>
> 	^false

Okay.

>
>>> Because it serves to replace isXXXX pattern, and not adding something
>>> new (i.e. more 'userful'). So, answering false for Object class fits
>>> well for this purpose.
>>>
>>> And of course solution to that problem is simple:
>>> - avoid writing code in style, which require isXXX tests and then
>>> branching. Nicely written code should use message dispatch instead.
>>> Too bad, we are not living in perfect world :)
>>
>> Is it better to flood superclasses with no-op extension methods?
>>
>
> Absolutely no. But the proposal is from June 2009 and was supported
> by Andreas, whose judgement I trust a lot. This is the first time in
> over 10 years of squeaking that I have ever suggested adding a method
> to Object, so it's really not too much of a flood. And I promise
> never to do it again ;-)

The flooding is unrelated to #is:. It would be the side effect of Igor's 
suggestion: "- avoid writing code in style, which require isXXX tests and 
then branching.".
Let's see the above example: SmalltalkImage >> #cleanUpUndoCommands. It 
sends #isMorph to all objects and then does something if the result is 
true.
How could it be modified to satisfy Igor's suggestion?
Implement Object >> #cleanUpUndoCommands which does nothing (this is the 
bloat) and implement Morph >> #cleanUpUndoCommands which does the real 
work. Then send this method from SmalltalkImage's method to all objects. 
No branching on the result of a #is* method, but an extra method for 
Object. Why is this worse than using #isMorph? Because this method is 
hardly useful from any other code, but #isMorph is.


Levente

>
> Dave
>
>
>



More information about the Squeak-dev mailing list