Ha. And here I thought that such closures can be added and removed without the GC if nobody needs access to thisContext or similar. :-) Just push it on the stack and then pop it.
Best, Marcel Am 20.09.2023 20:30:10 schrieb Tobias Pape das.linux@gmx.de: Hi,
Taking Eliots point:
On 20. Sep 2023, at 20:10, Eliot Miranda wrote:
Hi Marcel,
hint: look at the bytecode. The bytecode compiler inlined most blocks into ifTrue:ifFalse: et al hence this
#() isEmpty ifTrue: ['hallo'] ifFalse: ['squeak']
produces no closures, compiling to conditional jump bytecodes. Whereas this
#() ifEmpty: ['hallo'] ifNotEmpty: ['squeak']
produces two closures as arguments.
The crucial thing is the _sender_ not the implementation of ifEmpty:ifNotEmpty: (The objects are created there, if at all)
Best regards -Tobias
Apologies about the text size change
_,,,^..^,,,_ (phone)
On Sep 19, 2023, at 4:14 AM, Marcel Taeumel via Squeak-dev wrote:
Hi all -- [ #() isEmpty ifTrue: ['hallo'] ifFalse: ['squeak'] ] bench '127,000,000 per second. 7.85 nanoseconds per run. 0 % GC time.' [ #() ifEmpty: ['hallo'] ifNotEmpty: ['squeak'] ] bench 7,580,000 per second. 132 nanoseconds per run. 78.0088 % GC time.'
Why is that? :-) Why is there an extra GC?
Here is the current implementation of #ifEmpty:ifNotEmpty:
ifEmpty: emptyBlock ifNotEmpty: notEmptyBlock self isEmpty ifTrue: [^ emptyBlock value]. ^ notEmptyBlock cull: self
Best, Marcel