On 01/12/2017 06:45 AM, Julien Delplanque wrote:
On 12/01/17 12:32, Henrik Nergaard wrote:
Ps. Using a symbol instead of a block reduces performance.
[ 1 to: 1e9 do: [ :each | each ] ] timeToRun. "0:00:00:02.463"
[ 1 to: 1e9 do: #yourself ] timeToRun. "0:00:00:11.468"
Wow, I used symbols to make the example clear but I didn't know that.
That's sad, I think it is sexier to use a symbol to do this kind of
things. :(

I'm not sure what this test is supposed to show. The first one is just a loop counting to 1 billion inlined in a method. The second one is a message send of #to:do: which is implemented as a whileTrue: loop which will send the #value: message to #yourself. Essentially, it is showing the time to evaluate "#yourself value: someInt" 1 billion times.

I think that a better test to show the performance difference is this:

[ 1 to: 1000000000 do: [ :i | [ :e | e ] value: i ] ] timeToRun. "0:00:00:14.917"

[ 1 to: 1000000000 do: [ :i | #yourself value: i ] ] timeToRun. "0:00:00:07.846"

These results might lead you to believe that symbols are faster than blocks. However, the first one is also creating 1 billion blocks. If we create the block once, then blocks are faster:

[ | b | b := [ :e | e ]. 1 to: 1000000000 do: [ :i | b value: i ] ] timeToRun. "0:00:00:04.515"

So, if you know how many blocks you will create and how often each block is evaluated, you could come up with the optimal solution. Or, you could just write your code so the intent is expressed clearly and not worry about performance until it is needed.


John Brant

Reply via email to