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