optimization

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

optimization

paolo.bernardi.67@gmail.com
hi all,
expressions based on constants are remembered/cached for next evalations?
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.

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

thanks
Paolo
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: optimization

Levente Uzonyi-2
On Sun, 24 Nov 2013, [hidden email] 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
> [hidden email]
> http://lists.squeakfoundation.org/mailman/listinfo/beginners
>
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners