# Strange performance of Outer [duplicate]

The following takes 0.07 seconds on my laptop.

list1 = RandomReal[1.,1000000];
(Outer[Times, list1, RandomReal[1., 2]];) // AbsoluteTiming


But this takes 1.2 seconds:

list1 = RandomReal[1.,1000000];
(Outer[Times, list1, {1.,2.}];) // AbsoluteTiming


What is wrong here?

Both version 10.3 and 7 have this timing result.

## 1 Answer

It seems like RandomReal[1., 2] is automatically a packed array, whereas {1., 2.} is not. Notice;

(Outer[Times, list1, DeveloperToPackedArray@{1., 2.}];) // AbsoluteTiming // First
(* 0.032425 *)


whereas

(Outer[Times, list1, {1., 2.}];) // AbsoluteTiming // First
(* 0.542086 *)


Also:

list1 = DeveloperFromPackedArray@RandomReal[1., 1000000];
(Outer[Times, list1, RandomReal[1., 2]];) // AbsoluteTiming
(* 0.473775 *)


Packed arrays are good for both memory usage and for built-in Mathematica operations that are optimized for packed arrays (for instance). See What is a packed array?.

• Oh, my god! So we users have to pay attention to this? It is ridiculous that using {1.,2.} should be careful :( Nov 28, 2015 at 15:39
• I am so disappointed with mathematica on this case Nov 28, 2015 at 15:41
• I think it's a consequence of Mathematica's flexibility. Lists can store any combination of data types, but packed arrays require that Mathematica knows that the data types are all the same and knows what that data type is. Therefore, you have to tell it that the list can be a packed array. Just like any programming language, you have to have a lot of experience and knowledge about the language in order to optimize your code, especially if you are running operations that are numerically intensive. IMO, Mathematica makes basic optimization pretty easy. Nov 28, 2015 at 15:43
• I think it's because Plus is Listable and if that attribute is applied first, the array would have to be unpacked; instead, there is a special case when one of the arguments is a packed array. See Rob Knapp's talk (my comment under the what is a packed array question), or maybe it's discussed in one of the answers. Perhaps other functions could be made more efficient. Nov 28, 2015 at 16:59
• @matheorem Outer is compilable. From your comments it sounds like you would prefer the behavior of, for example, outerTimes = Compile[{{l1, _Real, 1}, {l2, _Real, 1}}, Outer[Times, l1, l2]]. Nov 28, 2015 at 22:05