Here is the example, copied from here
square = Function[x, x^2];
square1 = #^2 &;
the timing and unpacking status shows
data = RandomReal[{0, 10}, {10000}];
AbsoluteTiming[Developer`PackedArrayQ[Map[square, data]]]
AbsoluteTiming[Developer`PackedArrayQ[tmp1 = Map[square1, data]]]
{0.000771589, True}
{0.000748647, True}
Now we add external variable into these two definition.
a = 1
square = Function[x, x^2 + a];
square1 = #^2 + a &;
and time it again, you got
{0.0336384, False}
{0.0062035, True}
we can see &
is still autocompiled, while Function
is not. Why? I think the documentation treats them as identical way of writing. This distinction is oddly subtle, I just found it today. What is bad is that without Function
, we can not give parameters names, thus less readability.
square = Function[x, x^2 + a];
isn't compared inMap
. I think this can be considered as another evidence that the auto-compilation of pure function is still not that stable currently. $\endgroup$square
is slower thansquare1
without compilation. You can useTrace
to see that there is a significant difference in the evaluation. Autocompilation can be switched of withSetSystemOptions["CompileOptions" -> {"MapCompileLength" -> \[Infinity]}]
and increases the difference in your second case, while it removes the difference in your first case. $\endgroup$Function
is to make use of autocompilation. When&
andFunction
both been autocompiled, they are of same speed. If speed is not of concern, then I can just usesquare2[x_] := x^2;
, and in case of"MapCompileLength" -> \[Infinity]
,square2[x_] := x^2
is actually faster thanFunction
. $\endgroup$square2 = With[{a = a}, Function[x, x^2 + a]]
would autocompile properly. Maybe"InlineExternalDefinitions"
is handled differently? $\endgroup$SetSystemOptions[ "CompileOptions" -> {"CompileReportFailure" -> True, "InternalCompileMessages" -> True}]
can be used to switch on the generation of an error message. $\endgroup$