Bonjour,
Supposer une capacité d'optimisation du compilateur permet généralement d'écrire du code plus efficace. Ainsi, je souhaites avoir une implémentation assez spécifique d'une structure de graphe qui soit efficace pour l'usage que j'en ai. Si je choisis d'indexer les sommets de ce graphe par des entiers, et que j'utilise des map de la librairie standard, je peux renvoyer ces entiers dans les fonctions successeurs, ou iter. Ensuite, l'utilisateur donnera ces index pour appeler d'autres fonctions. Le soucis, c'est qu'on refera alors un parcours de la structure de donnée pour trouver le sommet indexé.
Une solution à ce problème est de renvoyer à l'utilisateur un type abstrait représentant les sommets mais contenant toutes les informations associées à ce sommet, de sorte que lorsque l'on appelle une fonction avec ce sommet, la fonction n'ait plus qu'à extraire l'information du tas.
C'est là que le compilateur intervient. Après inlining, il doit remarquer qu'en fait, une seule information du tas était nécessaire, et que donc la construction du tas était inutile. De cette manière, l'abstraction de l'objet "sommet" ne créée aucune perte de performances.
Seulement j'ai un doute sur l'utilisation de ce genre d'optimisation. J'ai construit le programme simple suivant :
La fonction f embarque dans un couple deux informations. La fonction g extrait l'une de ces deux informations. Dans le code en dessous, on se rend compte qu'embarquer 2 dans le couple était en fait inutile. On obtient donc un programme trivialement équivalent à celui-ci :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 let f x y = (x,y) ;; let g (x,y) = x ;; let _ = let x = f 1 2 in let y = g x in Format.printf "%d\n" y ;;
Oui mais voilà, ce qu'ocamlopt produit :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 let _ = Format.printf "%d\n" 1 ;;
qui semble un peu plus complexe que l'idéal. Faut il renoncer à l'idée initiale ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 camlTest__entry: subl $4, %esp .L105: movl $camlTest__3, %eax movl %eax, camlTest movl $camlTest__2, %eax movl %eax, camlTest + 4 call caml_alloc2 .L106: leal 4(%eax), %eax movl $2048, -4(%eax) movl $3, (%eax) movl $5, 4(%eax) movl camlTest + 4, %ebx movl (%ebx), %ecx call *%ecx .L107: movl %eax, 0(%esp) movl $camlTest__1, %eax call camlFormat__printf_1770 .L108: movl %eax, %ebx movl (%ebx), %ecx movl 0(%esp), %eax call *%ecx .L109: movl $1, %eax addl $4, %esp ret
Partager