For example
In[342]:=
test3 = Flatten[Outer[Plus, Range[1000], Range[1000]],
1]; // AbsoluteTiming
Out[342]= {0.0198735, Null}
returns PackedArray (examined by Developer`PackedArrayQ[test3] ), while
In[334]:=
test3 = Flatten[Outer[#1 + #2 &, Range[1000], Range[1000]],
1]; // AbsoluteTiming
Out[334]= {0.822719, Null}
Unpacks. And we can see the huge timing difference.
Why different unpacking behaviour of Outer
?
What is more, the first Outer
example is the fastest possible code. Even faster than Compiled to C target code.
Oddly, Map
pure function and Map
built-in Total
is slow
In[281]:=
test2 = (#[[1]] + #[[2]] &) /@
Tuples[{Range[1000], Range[1000]}]; // AbsoluteTiming
Out[281]= {0.214871, Null}
In[340]:=
test22 = Total /@ Tuples[{Range[1000], Range[1000]}]; // AbsoluteTiming
Out[340]= {0.176941, Null}
Though both of the above returns PackedArray. And they are much slower than trivial Table
In[299]:=
test4 = Flatten[Table[i + j, {i, 1, 1000}, {j, 1, 1000}],
1]; // AbsoluteTiming
Out[299]= {0.0530814, Null}
The performance is so inconsistent. I was trying to calculate something like 251001 (-1 + #1) + 501 (-1 + #2) + #3
& on Tuples[{{1}, Range[501], Range[501]}]
, found it is a bottleneck, Tried Map
, Outer
, ApplyAll
(Apply unpacks), sophisticated Compile
, and finally found trivial Table
is already almost the same efficiency as Compile!!