I do not understand why the function With[{y = #}, {y, y, y}] & maps faster than the function {#, #, #} &. The difference is appreciable in my system.
Module[{p = RandomInteger[1000, 100], n = 1000000,
f = Function[Null, {#, #, #}],
g = Function[Null, {#, #, #}, HoldAll]}, {
Timing[Do[With[{y = #}, {y, y, y}] & /@ p, {n}]],
Timing[Do[{#, #, #} & /@ p, {n}]],
Timing[Do[f /@ p, {n}]],
Timing[Do[g /@ p, {n}]]}]
(*{{9.031250, Null}, {11.078125, Null}, {11.125000, Null}, {11.203125, Null}}*)
I thought that the time saving came from With having attribute HoldAll but the timing of the function g above is similar to the other slower functions.
Is there any rule of thumbs to use With to speed up the code?
The question has been partially answered by Alexey's comment below. Nevertheless, would the following rule be valid (?): Compiled numerical functions that use the input in several places benefit from With.
{15.0229, 16.8793, 17.0353, 17.1757}as timings. The difference is small but really surprising. Probably it is somehow related to auto-compilation. – Alexey Popkov Aug 09 '16 at 06:53p = RandomInteger[1000, 100]top = RandomInteger[1000, 50]results in a drastic increase of the timings{78.6, 27.6, 27.7, 36.5}. The function withWithis now slower as expected. – Hector Aug 09 '16 at 07:16