8

In general, to define a function, we often use f[x_]. Another way is to use pure function (full form and shorthand). I want to test the performance of these function declaration.

Original test:

Here is a simple test:

ClearAll[f1, f2, f3, f4];

f1[x_] = 3 x; f2[x_] := 3 x; f3 = Function[x, 3 x]; f4 = (3 #) &;

l1 = Range[10^7];

f1 /@ l1; // Timing f2 /@ l1; // Timing f3 /@ l1; // Timing f4 /@ l1; // Timing

f1[l1]; // Timing f2[l1]; // Timing f3[l1]; // Timing f4[l1]; // Timing

And here is a result:

{5.04688, Null}

{5.29688, Null}

{0.21875, Null}

{0.171875, Null}

{0., Null}

{0.015625, Null}

{0., Null}

{0., Null}

So here is what I've learned: (It's not new here, many people have shown it).

1. Use built-in Listability: f1[l1] is much faster than f1 /@ l1;

2. Pure function is the fastest solution f4 = (3 #) &; is faster than f3 = Function[x, 3 x];, and faster than f2[x_] := 3 x;

3. Searching the global rule definition is costly f2[x_] := 3 x; searching global rule is inside the loop.

f2 /@ l1; // Timing
{5.29688, Null}

f3 /@ l1; // Timing {0.21875, Null}

Update 1: To avoid the built-in Listable over a list, I change the definition.

ClearAll[f1, f2, f3, f4];

f1[x_] = something[x]; f2[x_] := something[x]; f3 = Function[x, something[x]]; f4 = (something[#]) &;

Repeat these functions on a list:

l1 = Range[10^6];

f1 /@ l1; // Timing f2 /@ l1; // Timing f3 /@ l1; // Timing f4 /@ l1; // Timing

Here is what I get:

{0.390625, Null}

{0.390625, Null}

{0.5, Null}

{0.296875, Null}

The pure function shorthand is the fastest. And the classic function declaration is very slow (50 times slower). I wonder why? Is it due to the x Pattern, or due to the difference between Set and SetDelay?

When do I need to do an intensive calculation, which type of function declaration I should use?

Conclusion: I found that using pure function is very fast. Adding the global rewrite rule in the inner loop is slow. Each time we define a new function, a rewrite rule is added. Term rewriting is expensive inside the loop. (For the built-in function, don't forget the Listability). For the complex function, use /@ combined with pure function.

Michael E2
  • 235,386
  • 17
  • 334
  • 747
Nam Nguyen
  • 1,761
  • 13
  • 24

0 Answers0