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. $\endgroup$ – Alexey Popkov Aug 9 '16 at 6: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 withWith
is now slower as expected. $\endgroup$ – Hector Aug 9 '16 at 7:16