On 01/12/2017 08:03 AM, Henrik Nergaard wrote:
The test was meant to show the overhead when a symbol is used as a message 
argument instead of a block, not the evaluation of each of them by #value:
--------------------------------------------
#(a b c) collect: #asUppercase "#('A' 'B' 'C')"
#(a b c) collect: [ :each | each asUppercase ]. "#('A' 'B' 'C')"
--------------------------------------------

Passing a symbol will be faster than creating and then passing a block. If the block has already been creating then both should be about the same speed. Evaluating a block is faster than evaluating a symbol like a block (i.e., sending the #value: message).

Your initial tests used the #to:do: message. That message gets inlined when the last argument is a one argument block. The code for the first example "1 to: 1e9 do: [ :each | each ]" would have been inlined to look something like this:

        | current end |
        end := 1e9.
        current := 1.
        [current <= end] whileTrue: [current := current + 1]

So there are no "real" block arguments as the "[:each | each]" gets removed.

BTW, there is a bug in the #to:do: inlining. The first argument is evaluated before the receiver. Here's a test case that fails:

| stream |
stream := ReadStream on: #(2 1).
stream next to: stream next
        do: [ :i | self error: 'This should not occur' ]

This should be evaluated as "2 to: 1 do: ...". Instead it is evaluated as "1 to: 2 do: ..." .


John Brant

Reply via email to