The benefits of pure function

Today I read about a pure function, confused about its use:

A function is called pure if it returns the same set of values ​​for the same set of inputs and has no observable side effects.

eg. strlen() is a pure function, and rand() is unclean.

 __attribute__ ((pure)) int fun(int i) { return i*i; } int main() { int i=10; printf("%d",fun(i));//outputs 100 return 0; } 

http://ideone.com/33XJU

The above program behaves the same as in the absence of a pure declaration.

What are the benefits of declaring a function as pure [if there is no change in output]?

+76
c pure-virtual
Jun 22 2018-12-12T00: 00Z
source share
6 answers

pure lets the compiler know that it can do certain optimizations regarding a function: imagine some code, for example

 for (int i = 0; i < 1000; i++) { printf("%d", fun(10)); } 

With a pure function, the compiler can know that it needs to evaluate fun(10) once and once, and not 1000 times. For a complex function, this is a big win.

+135
Jun 22 2018-12-12T00:
source share

When you say that the function is "pure", you guarantee that it has no externally visible side effects (and, as the comment says, if you lie, bad things can happen). Knowing that the pure function has advantages for the compiler, which can use this knowledge to perform certain optimizations.

Here is what the GCC documentation says about the pure attribute:

clean

Many functions have no effects other than the return value and their return. The value depends only on parameters and / or global variables. Such a function may be subject to the general exclusion of subexpressions and loop optimization in the same way as the arithmetic operator. These functions must be declared with the pure attribute. For example,

  int square (int) __attribute__ ((pure)); 

Philip's answer already shows how to know that a function is β€œclean” can help optimize loops.

Here is one of them to eliminate a common sub-expression (assuming foo is clean):

 a = foo (99) * x + y; b = foo (99) * x + z; 

Can be:

 _tmp = foo (99) * x; a = _tmp + y; b = _tmp + z; 
+33
Jun 22 2018-12-12T00:
source share

In addition to the possible advantages at run time, a pure function is much easier to reason when reading code. In addition, it is much easier to check a pure function, since you know that the return value depends only on the parameter values.

+27
Jun 22 2018-12-12T00:
source share

Impure function

 int foo(int x, int y) // possible side-effects 

as an extension of pure function

 int bar(int x, int y) // guaranteed no side-effects 

in which, in addition to the explicit arguments to the x, y function, the rest of the universe (or anything your computer can interact with) as an implicit potential input. Similarly, besides an explicit integer return value, everything that your computer can write is implicitly part of the return value.

It should be clear why it is much easier to talk about a pure function than not a pure one.

+15
Jun 22 '12 at 15:08
source share

As an addition, I would like to mention that C ++ 11 encodes some things using the constexpr keyword. Example:

 #include <iostream> #include <cstring> constexpr unsigned static_strlen(const char * str, unsigned offset = 0) { return (*str == '\0') ? offset : static_strlen(str + 1, offset + 1); } constexpr const char * str = "asdfjkl;"; constexpr unsigned len = static_strlen(str); //MUST be evaluated at compile time //so, for example, this: int arr[len]; is legal, as len is a constant. int main() { std::cout << len << std::endl << std::strlen(str) << std::endl; return 0; } 

Constraints on using constexpr make it so that the function is clearly clean. That way, the compiler can optimize more aggressively (just make sure you use tail recursion, please!) And evaluate the function at compile time instead of runtime.

So, to answer your question, this is that if you use C ++ (I know you said C, but they are connected), writing a clean function in the correct style allows the compiler to do all kinds of cool things with the function :-)

+7
Jun 22 '12 at 15:40
source share

In general, Pure functions have 3 advantages over unclean functions that the compiler can use:

Caching

Suppose you have a pure function f , which is called 100,000 times, since it is deterministic and depends only on its parameters, the compiler can calculate its value once and use it if necessary

Parallelism

Pure functions are not read or written to any shared memory and therefore can be run in separate threads without any unexpected consequences.

Pass by link

The function f(struct t) takes its argument t by value, and on the other hand, the compiler can pass t reference to f if it is declared as clean, ensuring that the value of t does not change and will get a performance gain




In addition to compile-time considerations, pure functions can be tested quite simply: just call them.

No need to create objects or connect to a DB / file system.

+3
May 13 '15 at 18:53
source share



All Articles