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