En informatique, l'extension inline, ou inlining, est une optimisation d'un compilateur qui remplace un appel de fonction par le code de cette fonction. Cette optimisation vise à réduire le temps d'exécution ainsi que la consommation mémoire. Toutefois, l'extension inline peut augmenter la taille du programme (par la répétition du code d'une fonction).

Certains langages (par exemple le C ou le C++) ont un mot clé inline attachable à la définition d'une fonction. Ce mot clé indique au compilateur qu'il devrait essayer d'étendre cette fonction. Le compilateur pourra ensuite utiliser plusieurs heuristiques pour décider quelle fonction doit être étendue inline.

Implémentation

[modifier | modifier le code]

Dès que le compilateur décide d'étendre une fonction, l'opération est assez simple. La modification peut se faire au niveau du code source, d'une représentation intermédiaire (comme un arbre syntaxique abstrait) ou une représentation de bas niveau (bytecode ou autre).

Le principe est le calcul des valeurs des arguments, leur stockage dans des variables et finalement l'insertion du code de la fonction en lieu et place de l'appel.

Un éditeur de liens peut également implanter une extension inline. Cela permet de ne pas subir la frontière d'une bibliothèque dont le code n'est pas connu et ainsi potentiellement d'optimiser encore plus le code d'une application.

Finalement, un environnement d'exécution peut également inclure une extension inline. Par exemple, la machine virtuelle Java peut utiliser les statistiques d'exécution pour décider de fonctions à étendre.

Exemple

[modifier | modifier le code]

Voici un exemple d'extension à la main sur du code en C. Admettons que l'on ait une fonction pred qui doit être appelée par une fonction f :

int pred(int x) {
    if (x == 0)
       return 0;
    else
       return x - 1;
}

Sans extension, la fonction f s'écrit :

 int f(int y) {
     return pred(y) + pred(0) + pred(y+1);
 }

La fonction f peut également s'écrire, après extension :

int f(int y) {
    int temp = 0;
    if (y   == 0) temp += 0; else temp += y       - 1; /* (1) */
    if (0   == 0) temp += 0; else temp += 0       - 1; /* (2) */
    if (y+1 == 0) temp += 0; else temp += (y + 1) - 1; /* (3) */
    return temp;
}

Il s'agit d'un exemple à la main. Pour indiquer au compilateur C que la fonction peut être étendue, il faudrait ajouter le mot clé inline dans la déclaration de la fonction pred.

Avantages

[modifier | modifier le code]

Une extension inline permet en soi d'éliminer le coût d'un appel de fonction, mais son intérêt principal est de rendre possible d'autres optimisations. En effet, le remplacement de l'appel de la fonction par le code permet au compilateur des optimisations qui ne sont pas possibles à travers un appel de fonction.

Par exemple, une condition peut être analysée comme toujours vraie (ou fausse) dans le contexte d'un appel particulier ce qui peut permettre au compilateur d'éliminer le test. L'extension inline peut également rendre possible la détection de code mort, l'optimisation d'invariant, ou encore l'élimination de variables d'induction.

Dans l'exemple précédent en C, on trouve les possibilités d'optimisation suivante

Le résultat est alors:

int f(int y) {
    if (y == 0)
        return y;            /* or return 0 */
    else if (y == -1)
        return y - 1;        /* or return -2 */
    else
        return y + y - 1;
}

Inconvénients

[modifier | modifier le code]

Le remplacement effectué lors d'une extension inline peut diminuer la performance :

Les auteurs de compilateurs utilisent alors un ensemble d'heuristiques pour choisir quelles fonctions étendre dans le but d'améliorer la performance plutôt que de la dégrader.

Limitations

[modifier | modifier le code]

Il n'est pas toujours possible de pratiquer une extension inline.

Le cas d'une fonction récursive est un problème. Le compilateur doit remplacer le code de la fonction à l'intérieur de son code, ce qui provoque une boucle sans fin.

Cela implique que chaque compilateur doit choisir quelle fonction étendre en fonction des mécanismes d'optimisation disponible.

Utilisation

[modifier | modifier le code]

La plupart des compilateurs modernes utilisent beaucoup l'inlining car l'augmentation de la taille du code pose rarement problème et les progrès au niveau mémoire ont été plus rapides que ceux des processeurs.

L'inlining est une optimisation fondamentale pour les langages fonctionnels et objet. Dans ces cas, l'extension du code permet souvent d'appliquer de nombreuses optimisations permettant d'améliorer énormément la performance du code.

Voir aussi

[modifier | modifier le code]

Liens externes

[modifier | modifier le code]

Références

[modifier | modifier le code]