RE: [Pharo-users] Re: Block evaluation with n+1 arguments

Steven Kelly <[email protected]> Wed, 12 Apr 2023 08:11:59 +0000
Newsgroups gmane.comp.lang.smalltalk.vwnc,gmane.comp.lang.smalltalk.pharo.user
Message-ID <HE1P194MB0027FBF6559F02DBF5A88A2BA69B9@HE1P194MB0027.EURP194.PROD.OUTLOOK.COM>
Like Richard Sargent, I'd prefer to write the code so it's easy to understand. But without knowing all the reasons and semantics of what you're trying to do, I'll just throw a couple of technical approaches into the mix.

1) Change the source object so it can also return multiple values as a tuple with an extra first element.

2) Build the array once, and simply copy values into it each time:
allArgs := Array new: (numArgs := block numArgs).
1 to: 1000 do: [:i | | args |
	args := source compute: i.
	allArgs at: 1 put: i.
	allArgs replaceFrom: 2 to: numArgs with: args startingAt: 1.
	block valueWithArguments: allArgs].

You could combine 1) and 2) so the source object knows how to fill an existing array: 
source compute: i fill: allArgs

All the best,
Steve

Steffen Märcker wrote Tuesday, April 11, 2023 7:44 PM:
> The objective is to avoid unnecessary object creation in a tight loop that
> interfaces between a value source and a block that processes the values.
> - The source object returns multiple values as a tuple (for good reasons).
> - The block processes theses values but needs another argument (at the
> first place).
> We do not know the number of values at compile time but know that they
> match the arity of the block. Something like this (though more involved in
> practice):
> 
> 	(1 to: 1000) do: [:i | | args |
> 		args := source compute: i.
> 		block valueWithArguments: {i} , args ]
> 
> Since prepending the tuple with the first argument and then sending
> #valueWithArguments: creates an intermediate Array, I wonder whether we
> can
> avoid (some of) that overhead in the loop without changing this structure.
> Note, "{i}, args" is only for illustration and creates an additional third
> array as Steve already pointed out.
> 
> To sum up the discussion so far:
> - If possible, change the structure, e.g., processing the tuple directly.
> - Fast primitives exist for the special cases of 1, 2 and 3 arguments only.
> - Code for > 3 arguments would have to use #valueWithArguments: after all.
> 
> Did I miss something?
> 
> Kind regards,
> Steffen