Go Down

Topic: Question optimisation du code (Read 449 times) previous topic - next topic

MiGaNuTs

Bonjour,

je m'interroge sur quel est la meilleure façon de faire "tourner en rond" une variable.
En l'occurrence, quelle est le mieux entre ces deux codes possible

Code: [Select]

i++;
if (i>n) {i=0;}


Code: [Select]

i=(i+1)%n;


Le deuxième faisant l'impasse sur un if me semble a priori plus rapide, mais pas aussi clair a la relecture. Et puis pas sur que le modulo soit plus rapide qu'une condition au final.

haifger

L'opérateur modulo tient peut-être en un seul caractère en C, mais une fois traduit en langage machine il prendra une foule d'instructions avec branchements conditionnels et autres (même si toi tu ne les vois pas dans ton code).

Le seul cas que j'arrive à imaginer dans lequel la deuxième solution serait plus efficace que la première serait que « n » soit une puissance de 2, auquel cas le modulo se simplifie en un « ET bit à bit », mais je ne sais pas si le compilateur est capable de faire cette optimisation tout seul ou s'il faut le coder à la mano.

Voilà, d'un autre côté je dis tout ça de tête et j'ai rien testé, à prendre au conditionnel donc :)

Artouste


Bonjour,

je m'interroge sur quel est la meilleure façon de faire "tourner en rond" une variable.
En l'occurrence, quelle est le mieux entre ces deux codes possible

Code: [Select]

i++;
if (i>n) {i=0;}


Code: [Select]

i=(i+1)%n;


Le deuxième faisant l'impasse sur un if me semble a priori plus rapide, mais pas aussi clair a la relecture. Et puis pas sur que le modulo soit plus rapide qu'une condition au final.

bonjour
sans que ce soit une verité absolu, la concision du code injecté est souvent un bon indicateur de vitesse d'execution

sur uno et en ide 1.04

ça = 490 octets
Quote
byte i=0;
byte n=255;
void setup() {
}

void loop() {
i++;
if (i>n) {i=0;}
}



et avec ça 568 bytes
Quote
byte i=0;
byte n=255;
void setup() {
}

void loop() {
i=(i+1)%n;
}



skywodd

Bonjour,

Pour optimiser une boucle : ne pas chercher à faire compliqué.

La meilleur optimisation :
Code: [Select]
for (byte i = 0; i < n; ++i) {
  // ...
}


Ou si tu n'utilises pas "i" mais que tu veut juste boucler "n fois" :
Code: [Select]
for (byte i = (n + 1); i; --i) {
  // ...
}

(le compilateur aura ici un test à faire en moins par boucle)

Et si tu veut faire une boucle "non locale" :
Code: [Select]
static const byte n = 255;

void loop() {
  static byte i = 0;
  // ...
  if (++i == n) i = 0;
}

(théoriquement tu n'est pas sensé avoir à faire ce genre de boucle si ton code est bien pensé)
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

Go Up