Using Array and Table Functions in Mathematica. Which is best when

后端 未结 5 1987
执念已碎
执念已碎 2021-01-30 14:38

I have been mostly a Table functions user in mathematica. However I have noticed that in several examples where I used Array instead of Table to express the same result, it ran

5条回答
  •  太阳男子
    2021-01-30 15:03

    One reason Array may be faster is that it often compiles its first argument better.

    In Mathematica 7:

    In[1]:= SystemOptions[CompileOptions -> ArrayCompileLength]
    
    Out[1]= {"CompileOptions" -> {"ArrayCompileLength" -> 250}}
    

    and

    In[2]:= SystemOptions[CompileOptions -> TableCompileLength]
    
    Out[2]= {"CompileOptions" -> {"TableCompileLength" -> 250}}
    

    So one can infer that Array and Table should compile at the same point.

    But let's try it. I will be making use of Timo's timeAvg function:

    n = 15;
    Array[Mod[#^2, 5]*(1 + #2) &, {n, n}] // timeAvg
    Table[Mod[i^2, 5]*(1 + j), {i, n}, {j, n}] // timeAvg
    
    (* Out = 0.00034496 *)
    
    (* Out = 0.00030016 *)
    
    n = 16;
    Array[Mod[#^2, 5]*(1 + #2) &, {n, n}] // timeAvg
    Table[Mod[i^2, 5]*(1 + j), {i, n}, {j, n}] // timeAvg
    
    (* Out = 0.000060032 *)
    
    (* Out = 0.0005008   *)
    

    What we see is that Array is able to compile Mod[#^2, 5]*(1 + #2) & while Table is not able to compile Mod[i^2, 5]*(1 + j) and therefore for Array becomes faster when the CompileLength is reached. Many functions are not so favorable. If you merely change multiplication to division in the function, which results in a rational rather than integer result, then this auto-compile does not happen, and Table is faster:

    n = 15;
    Array[Mod[#^2, 5]/(1 + #2) &, {n, n}] // timeAvg
    Table[Mod[i^2, 5]/(1 + j), {i, n}, {j, n}] // timeAvg
    
    (* Out = 0.000576   *)
    
    (* Out = 0.00042496 *)
    
    n = 16;
    Array[Mod[#^2, 5]/(1 + #2) &, {n, n}] // timeAvg
    Table[Mod[i^2, 5]/(1 + j), {i, n}, {j, n}] // timeAvg
    
    (* Out = 0.0005744  *)
    
    (* Out = 0.0004352  *)
    

    But what if we can make this compile too? If we use floating point numbers, done by starting with 1., we get Real output, which can be compiled:

    n = 15;
    Array[Mod[#^2, 5]/(1 + #2) &, {n, n}, 1.] // timeAvg
    Table[Mod[i^2, 5]/(1 + j), {i, 1., n}, {j, 1., n}] // timeAvg
    
    (* Out = 0.0006256  *)
    
    (* Out = 0.00047488 *)
    
    n = 16;
    Array[Mod[#^2, 5]/(1 + #2) &, {n, n}, 1.] // timeAvg
    Table[Mod[i^2, 5]/(1 + j), {i, 1., n}, {j, 1., n}] // timeAvg
    
    (* Out = 0.00010528 *)
    
    (* Out = 0.00053472 *)
    

    And once again, Array is faster on the larger dimension array.

提交回复
热议问题