In Mathematica a vector (or rectangular array) containing all machine size integers or floats may be stored in a packed array. These objects take less memory, and some operatio
First, to avoid confusion, take a look at an example whose results are all representable as hardware machine precision numbers, which must all be less than
In[1]:= $MaxMachineNumber
Out[1]= 1.79769*10^308
Your Total example already had this nice (and fast) property. Here is a variant on your Times example using machine numbers:
In[2]:= lst = RandomReal[{0.99, 1.01}, 5000000];
Times @@ lst // Timing
Out[3]= {1.435, 1.38851*10^-38}
Now we can use Compile to make a compiled function to perform this operation efficiently:
In[4]:= listproduct =
Compile[{{l, _Real, 1}},
Module[{tot = 1.}, Do[tot *= x, {x, l}]; tot]]
Out[4]= CompiledFunction[{l},Module[{tot=1.},Do[tot*=x,{x,l}];tot],-CompiledCode-]
It's much faster:
In[5]:= listproduct[lst] // Timing
Out[5]= {0.141, 1.38851*10^-38}
Assuming you have a C compiler and Mathematica 8, you can also automatically compile all the way to C code. A temporary DLL is created and linked back into Mathematica at run-time.
In[6]:= compiledlistproduct =
Compile[{{l, _Real, 1}},
Module[{tot = 1.}, Do[tot *= x, {x, l}]; tot],
CompilationTarget -> "C"]
Out[6]= CompiledFunction[{l},Module[{tot=1.},Do[tot*=x,{x,l}];tot],-CompiledCode-]
This gives performance not much different to that which a built-in Mathematica function would have:
In[7]:= compiledlistproduct[lst] // Timing
Out[7]= {0.015, 1.38851*10^-38}
Note that if your product really will go beyond $MaxMachineNumber (or $MinMachineNumber), then you are better off sticking with Apply[Times, list]
. The same comment applies to Total, if your results can get that big:
In[11]:= lst = RandomReal[10^305, 5000000];
Plus @@ lst // Timing
Out[12]= {1.435, 2.499873364498981*10^311}
In[13]:= lst = RandomReal[10^305, 5000000];
Total[lst] // Timing
Out[14]= {1.576, 2.500061580905602*10^311}