[Newbies] optimization

Levente Uzonyi leves at elte.hu
Sun Nov 24 15:39:50 UTC 2013


On Sun, 24 Nov 2013, paolo.bernardi.67 at gmail.com wrote:

> hi all,
> expressions based on constants are remembered/cached for next evalations?

No they are not.

> If I compile:
>
> Foo>>wakeUpTime
>    ^ '6:30 am' asTime
>
> I can see that bytecode still send #asTime to the string '6:30 am'.
> It means that each time the piece of code will be evaluated
> the string will be parsed too, even if it is clear that it will never produce 
> a different object.

It's not constant at all. There are multiple ways to change the return 
value of that method. The easiest one is to change the implementation of 
String >> #asTime, or any method that is sent by that method, etc.

>
> Same thing for CodeBlocks.
> In:
> [ :t | t < '06:30' asTime ]
> the right argument of #> will never change... and I feel I'll spend a lot of 
> time
> on evaluating the same constant expressions during the execution of my 
> program...

Since message sends are late bound, it means that if you want to cache 
something, then you have to do it yourself. There are various ways to 
cache something. In your case if you know that you always want '6:30 am', 
then you can use a class variable to store it:

Foo class >> #initialize

 	WakeUpTime := '6:30 am' asTime

and then

Foo >> #wakeUpTime

 	^WakeUpTime

This technique has some drawbacks, notably that you'll have to evaluate 
the class side #initialize when you're writing the code. A common solution 
for this is to use lazy initalization instead:

Foo class >> #wakeUpTime

 	^WakeUpTime ifNil: [ WakeUpTime := '6:30 am' ]

and then

Foo >> #wakeUpTime

 	^self class wakeUpTime

You shouldn't use the class variable directly from the instance side in 
this case, otherwise you can't guarantee that it's initialized. If your 
class won't have subclasses, then you can use a class instance variable 
instead of a class variable, because it is not accessible directly from 
the instance side.

And there's also a hack, which caches the value in the method. I don't 
suggest you to use this techique, but it can be useful sometimes:

Foo >> #wakeUpTime

 	| cache |
 	cache := #(nil).
 	^(cache at: 1) ifNil: [ cache at: 1 put: '6:30 am' asTime ]


Levente

>
> thanks
> Paolo
> _______________________________________________
> Beginners mailing list
> Beginners at lists.squeakfoundation.org
> http://lists.squeakfoundation.org/mailman/listinfo/beginners
>


More information about the Beginners mailing list