# When are sparse arrays effective?

Sparse arrays are not effective in Mathematica 10. More computational time is needed to perform arithmetic operations on sparse arrays. Their size is also bigger than normal arrays. Here is a simple demonstration:

MatNormal = HankelMatrix[2000];
MatSparse = SparseArray[MatNormal];
multNormal = Timing[MatNormal.MatNormal];
multSparse = Timing[MatSparse.MatSparse];
Grid[{{"", "Normal", "Sparse", "Ratio"}, {"Computation Time",
multNormal[[1]], multSparse[[1]],
multSparse[[1]]/multNormal[[1]]}, {"Bytes Used",
ByteCount[multNormal[[2]]], ByteCount[multSparse[[2]]],
1.*ByteCount[multSparse[[2]]]/ByteCount[multNormal[[2]]]}},


\begin{array}{cccc} \text{} & \text{Normal} & \text{Sparse} & \text{Ratio} \\ \text{Computation Time} & 0.639604 & 8.923257 & 13.9512 \\ \text{Bytes Used} & 32000152 & 64017136 & 2.00053 \\ \end{array}

Am I missing something? What's the point of using sparse arrays?

• A Hankel Matrix is not particularly sparse, for one thing, you pay for updating zeroes in a sparse array, and the result of HankelMatrix is packed, so quite efficient (i.e, unpacked it's MUCH bigger). Learn where it is appropriate to use each kind...
– ciao
Commented Aug 21, 2015 at 22:30
• "what's the point of using sparse arrays then?" - it's supposed to be used for matrices with a lot of "background elements" ($0$ usually), and you have chosen a particularly good example of something that does not fit the bill. You get what you pay for, bub. Commented Aug 22, 2015 at 0:40
• @Guesswhoitis. I didnt know you were from Arkansas too, bub!
– kale
Commented Aug 22, 2015 at 2:41

You have shown that when the arrays are not sparse, using SparseArray is futile. Let's look at a case when it is sparse:

MatSparse = SparseArray[{{1, 1} -> 1, {2000, 2} -> 2, {3, 3} -> 3, {1, 2000} -> 4}];
MatNormal = Normal[MatSparse];
multNormal = Timing[MatNormal.MatNormal];
multSparse = Timing[MatSparse.MatSparse];
Grid[{{"", "Normal", "Sparse", "Ratio"}, {"Computation Time",
multNormal[[1]], multSparse[[1]],
multSparse[[1]]/multNormal[[1]]}, {"Bytes Used",
ByteCount[multNormal[[2]]], ByteCount[multSparse[[2]]],
1.*ByteCount[multSparse[[2]]]/ByteCount[multNormal[[2]]]}}]


Quite a difference!

• I +1 this, of course.... OP should also keep in mind that sparsity of eventual result comes into play, that is, in the OP and your Dot examples, the result does not become very sparse until the arguments themselves are already very sparse - so if one knows that even though the intermediate parts are reasonably sparse, if along the way you end up not sparse, might be worth just going with packed/unpacked non-sparse pieces....
– ciao
Commented Aug 22, 2015 at 6:43