TransWikia.com

Performance of pure function - Best way to define a function?

Mathematica Asked on January 17, 2021

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.

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP