Update
I think this behaviour was unintentional. It seems to have been fixed in V10.0.1.
Evidence that it is unintentional
The following command crashed the kernel in V9 (and I think V10.0.0)
Extract[1, {{}, All}]
and printed a funky message too (in V9). Anyway, it makes sense that we should put another pair of brackets around All
. Then, this was also weird:
Extract[1, {{}, {All}}]
which used to give Integer[]
Old answer
One thing to point out is that we can still use the third argument of Extract
if we use Span
. Indeed Extract
is now more general/flexible than Part
, except that you cannot use Extract
with Set
. Extract
appears to work quickly on packedarrays.
Timings
Here are some timing comparisons. Extract
can indeed beat Part
with Map
(or like in this answer, Apply
), as mentioned by rasher in comments. The result here will be a ragged array, so that we cannot suffice with a single call to Part
. Let
max=5*^6;
kk=1000;
mm=max/kk;
target = ConstantArray[Range[kk], mm]; ;
We have
PackedArrayQ[target]
True
If we also let
partSpans = Table[{ii, 1 ;; Mod[ii, kk, 1]}, {ii, 1, mm}]; ;
spans = Prepend[properSpans, {{}}];
Then
(out = Rest@Extract[target, spans]) // Timing // First
(pOut = Part[target, ##] & @@@ partSpans) // Timing // First
pOut === out
0.016991
0.020719
True
More and smaller sublists
For
max = 5*^6;
kk = 5;
mm = max/kk;
The timings become
0.673268 (*Extract*)
1.636892 (*Part*)
Extract reduces overhead
It turns out that the difference in timing between the solutions with Extract
and Part
is mainly due to overhead that is caused by Apply
. Another solution shows that the time taken by Part
is about the same as that taken by Extract
, even in this last case. For the timings below, I use the same parameters as in the last case above.
First we do all the overhead
(pCode =
Apply[
Part,
Hold@Evaluate@Array[Join[{target}, partSpans[[#]]] &, mm],
{2}
]) // Timing // First
5.176928
Then Part
is quite quick
(p2Out = ReleaseHold[pCode]) // Timing // First
p2Out === out === pOut
0.902468 (*Extract took 0.673268 *)
True
Possibly temporary note
This is a cleaner way to define pCode
(without the wrapper Hold
, but using a "delayed definition" instead). Syntax smyntax!
ReleaseHold@
Hold[SetDelayed][
Hold@pCode,
Apply[
Part,
Hold@Evaluate@Array[Join[{target}, partSpans[[#]]] &, mm],
{2}
]
] // Timing // First
{{}}
, or{0}
or{{101,4,3}}
... $\endgroup$