J’ai testé parce que ça m’intriguait quand même de pas avoir trouvé sur internet quelqu’un qui prouvait qu’il n’y avait aucune réelle différence
Alors j’ai utilisé ce code pour faire mes tests :
#include <stdio.h>
#include <time.h>
#define rep 10000
// On utilise le mot-clé `volatile` pour empêcher que le compilateur saute la
// boucle vide
void decl_for(void) {
volatile int i;
for (i = 0; i < rep; ++i) {
}
}
void decl_fn(void) {
for (volatile int i = 0; i < rep; ++i) {
}
}
int main(void) {
clock_t ta, td;
for (int i = 0; i < 10; ++i) {
printf("n°%d\t", i + 1);
td = clock();
for (int j = 0; j < rep; ++j) {
decl_for();
}
ta = clock();
long delta1 = ta - td;
printf("for : %ld\t", delta1);
td = clock();
for (int j = 0; j < rep; ++j) {
decl_fn();
}
ta = clock();
long delta2 = ta - td;
printf("fn : %ld\t", delta2);
printf("ecart : %ld\n", (delta1 - delta2) / CLOCKS_PER_SEC);
}
return 0;
}
Résultats
Ce qui me donne ces résultats :
n°1 for : 144047 fn : 135476 ecart : 8571
n°2 for : 144516 fn : 147876 ecart : -3360
n°3 for : 150797 fn : 135666 ecart : 15131
n°4 for : 153779 fn : 144821 ecart : 8958
n°5 for : 163571 fn : 155577 ecart : 7994
n°6 for : 141100 fn : 136226 ecart : 4874
n°7 for : 141100 fn : 135872 ecart : 5228
n°8 for : 140568 fn : 134942 ecart : 5626
n°9 for : 143267 fn : 135312 ecart : 7955
n°10 for : 143175 fn : 136072 ecart : 7103
On voit que déclarer dans la fonction et pas dans le for, c’est plus rapide,
sauf que j’ai compilé avec une tonne de truc de débogage :
-Wall -Wextra -Wshadow -Wcast-align -Wstrict-prototypes -fanalyzer -fsanitize=undefined -g
Voilà ce que ça donne sans argument donné au compilateur :
n°1 for : 147757 fn : 149087 ecart : -1330
n°2 for : 147442 fn : 146889 ecart : 553
n°3 for : 149774 fn : 142949 ecart : 6825
n°4 for : 150022 fn : 142218 ecart : 7804
n°5 for : 151124 fn : 144103 ecart : 7021
n°6 for : 148284 fn : 142159 ecart : 6125
n°7 for : 149724 fn : 145557 ecart : 4167
n°8 for : 162975 fn : 146997 ecart : 15978
n°9 for : 150409 fn : 142262 ecart : 8147
n°10 for : 150698 fn : 141019 ecart : 9679
Le résultat est le même, maintenant, avec l’option d’optimisation O3
:
n°1 for : 157722 fn : 162595 ecart : -4873
n°2 for : 162482 fn : 160296 ecart : 2186
n°3 for : 165359 fn : 161122 ecart : 4237
n°4 for : 177995 fn : 177640 ecart : 355
n°5 for : 165326 fn : 167349 ecart : -2023
n°6 for : 172356 fn : 160947 ecart : 11409
n°7 for : 163722 fn : 156314 ecart : 7408
n°8 for : 164267 fn : 158028 ecart : 6239
n°9 for : 164323 fn : 158746 ecart : 5577
n°10 for : 162714 fn : 156948 ecart : 5766
Toujours pareil, même en demandant à GCC d’optimiser.
Alors, il y a donc bien une différence entre les deux méthodes ?
Sur ma machine, avec ma version de gcc, oui. Mais peut-être que sur votre machine non.
Les résultats que j’ai présentés ci-dessus proviennent de mon PC portable. Quand je lance les mêmes tests, mais depuis mon PC fixe, voici ce que j’obtiens :
Avec les options de débogage :
n°1 for : 147380 fn : 174594 ecart : -27214
n°2 for : 154869 fn : 176800 ecart : -21931
n°3 for : 151584 fn : 175797 ecart : -24213
n°4 for : 150282 fn : 171719 ecart : -21437
n°5 for : 147962 fn : 172099 ecart : -24137
n°6 for : 148461 fn : 172433 ecart : -23972
n°7 for : 149758 fn : 172066 ecart : -22308
n°8 for : 149648 fn : 171500 ecart : -21852
n°9 for : 147577 fn : 173268 ecart : -25691
n°10 for : 149809 fn : 172117 ecart : -22308
Sans aucune option :
n°1 for : 193780 fn : 194501 ecart : -721
n°2 for : 194958 fn : 195128 ecart : -170
n°3 for : 194917 fn : 194266 ecart : 651
n°4 for : 194126 fn : 194726 ecart : -600
n°5 for : 194265 fn : 194346 ecart : -81
n°6 for : 193568 fn : 194979 ecart : -1411
n°7 for : 193909 fn : 194284 ecart : -375
n°8 for : 194475 fn : 194152 ecart : 323
n°9 for : 195083 fn : 195664 ecart : -581
n°10 for : 195224 fn : 194832 ecart : 392
Avec l’optimisation O3
:
n°1 for : 48481 fn : 194637 ecart : -146156
n°2 for : 48991 fn : 195717 ecart : -146726
n°3 for : 49006 fn : 195501 ecart : -146495
n°4 for : 49389 fn : 195469 ecart : -146080
n°5 for : 48953 fn : 194869 ecart : -145916
n°6 for : 48721 fn : 194756 ecart : -146035
n°7 for : 49230 fn : 196268 ecart : -147038
n°8 for : 49039 fn : 195210 ecart : -146171
n°9 for : 48959 fn : 195485 ecart : -146526
n°10 for : 48750 fn : 195087 ecart : -146337
Les résultats sont… plus que différent, ils sont carrément opposés !
L’écart est énormément réduit lorsque l’on compile sans aucun argument et cette
fois-ci, il est préférable d’initialiser dans le for
plutôt que dans la fonction.
Conclusion
Faites ce que vous voulez, le résultat dépendra de toute façon de votre machine. Et l’écart de performance est plus que négligeable.