81 votes

Avantages de la fonction pure

Aujourd'hui je lisais à propos de la fonction pure, je me suis confondu avec son utilisation:

Une fonction est dite pure si elle renvoie le même ensemble de valeurs pour le même ensemble d'entrées et n'a pas d'effets secondaires observables.

par exemple, strlen() est une fonction pure tandis que rand() est impure.

__attribute__ ((pure)) int fun(int i)
{
    return i*i;
}

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

http://ideone.com/33XJU

Le programme ci-dessus se comporte de la même manière qu'en l'absence de la déclaration pure.

Quels sont les avantages de déclarer une fonction comme pure[s'il n'y a pas de changement dans la sortie]?

144voto

Philip Kendall Points 3102

pure permet au compilateur de savoir qu'il peut effectuer certaines optimisations sur la fonction : imaginez un morceau de code comme

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

Avec une fonction pure, le compilateur peut savoir qu'il doit évaluer fun(10) une seule fois, au lieu de 1000 fois. Pour une fonction complexe, c'est une grande victoire.

34voto

ArjunShankar Points 8476

Lorsque vous dites qu'une fonction est 'pure', vous garantissez qu'elle n'a pas d'effets secondaires visibles à l'extérieur (et comme un commentaire le dit, si vous mentez, des choses mauvaises peuvent arriver). Savoir qu'une fonction est 'pure' présente des avantages pour le compilateur, qui peut utiliser cette connaissance pour effectuer certaines optimisations.

Voici ce que dit la documentation GCC à propos de l'attribut pure:

pure

De nombreuses fonctions n'ont aucun effet autre que la valeur de retour et leur valeur de retour dépend uniquement des paramètres et/ou des variables globales. Une telle fonction peut être soumise à l'élimination des expressions communes et à l'optimisation des boucles de la même manière qu'un opérateur arithmétique le serait. Ces fonctions doivent être déclarées avec l'attribut pure. Par exemple,

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

La réponse de Philip montre déjà comment savoir qu'une fonction est 'pure' peut aider avec les optimisations de boucle.

Voici un exemple d'élimination d'expression commune (en supposant que foo est pure):

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

Peut devenir:

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

28voto

Frerich Raabe Points 23711

En plus des éventuels avantages au moment de l'exécution, une fonction pure est beaucoup plus facile à comprendre lorsque vous lisez du code. De plus, il est beaucoup plus facile de tester une fonction pure puisque vous savez que la valeur de retour dépend uniquement des valeurs des paramètres.

15voto

Giorgio Points 1724

Une fonction non pure

int foo(int x, int y) // effets secondaires possibles

est comme une extension d'une fonction pure

int bar(int x, int y) // aucun effet secondaire garanti

dans laquelle vous avez, en plus des arguments de la fonction x, y, le reste de l'univers (ou tout ce avec quoi votre ordinateur peut communiquer) comme une entrée potentielle implicite. De même, en plus de la valeur de retour entière explicite, tout ce que votre ordinateur peut écrire fait implicitement partie de la valeur de retour.

Il devrait être clair pourquoi il est beaucoup plus facile de raisonner sur une fonction pure qu'une fonction non pure.

7voto

Robert Mason Points 1658

Tout simplement, j'aimerais mentionner que C++11 code un peu les choses en utilisant le mot-clé constexpr. Exemple :

#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); //DOIT être évalué au moment de la compilation
//donc, par exemple, ceci : int arr[len]; est légal, car len est une constante.

int main() {
    std::cout << len << std::endl << std::strlen(str) << std::endl;
    return 0;
}

Les restrictions sur l'utilisation de constexpr font que la fonction est prouvablement pure. De cette façon, le compilateur peut optimiser de manière plus agressive (assurez-vous simplement d'utiliser la récursion terminale, s'il vous plaît !) et d'évaluer la fonction au moment de la compilation au lieu du moment de l'exécution.

Donc, pour répondre à votre question, si vous utilisez C++ (je sais que vous avez dit C, mais ils sont liés), écrire une fonction pure dans le style correct permet au compilateur de faire toutes sortes de choses intéressantes avec la fonction :-)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X