I will answer a couple of your questions only.
Space efficiency
Packed arrays are significantly more space efficient. Example: Let's create an unpacked array, check its size, then do the same after packing it:
f = Developer`FromPackedArray[RandomReal[{-1, 1}, 10000]];
ByteCount[f]
ByteCount[Developer`ToPackedArray[f]]
(*
320040
80168
*)
Time efficiency
The difference seems to be how they are stored; packed arrays can only contain objects of the same type, so mma does not need to keep track of the type of each element. This can also speed up operations with them. Define
ClearAll[timeIt];
SetAttributes[timeIt, HoldAll]
timeIt[expr_] := Module[{t = Timing[expr;][[1]], tries = 1},
While[t < 1.,
tries *= 2;
t = AbsoluteTiming[Do[expr, {tries}];][[1]];
];
Return[t/tries]]
then
ClearAll[f, fpacked];
f = Developer`FromPackedArray[RandomReal[{-1, 1}, 500000]];
fpacked = Developer`ToPackedArray[RandomReal[{-1, 1}, 500000]];
fpacked.fpacked // timeIt
f.f // timeIt
Sin[fpacked] // timeIt
Sin[f] // timeIt
(*
0.0001610173
0.01167263
0.00487482
0.01420070
*)
Unpacking
To be warned of arrays being unpacked, you can do SetSystemOptions[PackedArrayOptions->UnpackMessage->True]
or, in versions after 7, On["Packing"]
(thanks to OleksandrR for pointing this out). The you see that eg Select
unpacks: try Select[fpacked, 3]
and a message is produced. Also assigning a value of different type to a packed array unpacks it: try fpacked[[2]] = 4
to see this.
This unpacking explains mysterious slowdowns in mma code most of the time for me.
Addressing
It appears that it is twice as slow to address a single element in a packed vs an unpacked array:
ClearAll[f, fpacked];
f = Developer`FromPackedArray[RandomReal[{-1, 1}, 500000]];
fpacked = Developer`ToPackedArray[RandomReal[{-1, 1}, 500000]];
fpacked[[763]] // timeIt
f[[763]] // timeIt
(*
4.249656*10^-7
2.347070*10^-7
*)
AppendTo
is not faster:
AppendTo[fpacked, 5.] // timeIt
AppendTo[f, 5.] // timeIt
(*
0.00592841
0.00584807
*)
I don't know if there are other kinds of addressing-like operations that are faster for packed arrays (I doubt it but could be wrong).
Aside
In the Developer`
context there are these names involving Packed
:
Select[
Names["Developer`*"],
Not@StringFreeQ[#, ___ ~~ "Packed" ~~ ___] &
]
(*
{"Developer`FromPackedArray", "Developer`PackedArrayForm",
"Developer`PackedArrayQ", "Developer`ToPackedArray"}
*)
Developer`PackedArrayForm
does this:
ClearAll[f, fpacked];
f = Developer`FromPackedArray[RandomInteger[{-1, 1}, 5]];
fpacked = Developer`ToPackedArray[RandomInteger[{-1, 1}, 5]];
Developer`PackedArrayForm[f]
Developer`PackedArrayForm[fpacked]
(*
{-1, -1, -1, -1, -1}
"PackedArray"[Integer, <5>]
*)
So, you could set $Post = Developer`PackedArrayForm
and then packed arrays would be displayed in a special way. I am not sure if this has any other sideeffects (this has been suggested in this great answer by ruebenko).