Salut à toutes et tous.
Dans ce cas où le message reçu n'a pas vocation à être conservé, une petite astuce pour optimiser les performances et la mémoire sur le code proposé ci dessous.
Au lieu de la définition de la fonction
void cmdExecution(String cmdText) {...}
il serait intéressant d'écrire plutôt
void cmdExecution(String& cmdText) {...}
Ce petit & n'a l'air de rien mais il va dire au compilateur de passer la chaîne en référence et non plus en copie (duplication). Le code va donc aller plus vite et mangera moins de mémoire à l'exécution (pas la peine d'allouer la mémoire pour la duplication de la chaîne et pas la peine de copier toutes les informations de la première chaîne dans la seconde, pour ensuite à la fin de la fonction passer encore du temps pour détruire l'objet et libérer la mémoire).
Pour voir ce qu'il se passe au niveau des pointeurs voilà un petit code:
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 30 31 32 33
| String message;
void imprimeStringReference(String& unTexte)
{
Serial.print(F("adresse de unTexte en mode Reference = 0x")); Serial.println((uint16_t) &unTexte, HEX);
Serial.println(unTexte);
unTexte = "au revoir"; // on modifie en fait la String message, il n'y a pas eu de copie locale
}
void imprimeStringCopy(String unTexte)
{
Serial.print(F("adresse de unTexte en mode Copy = 0x")); Serial.println((uint16_t) &unTexte, HEX);
Serial.println(unTexte);
unTexte = "au revoir"; // on modifie la copie locale, qui ensuite est virée de la mémoire
}
void setup() {
Serial.begin(115200);
Serial.print(F("adresse de message = 0x")); Serial.println((uint16_t) &message, HEX);
Serial.println();
message = String("Bonjour, T=") + String(millis()) + String(" ms"); // dynamique pour éviter une optimisation du compilateur
imprimeStringCopy(message);
Serial.print(F("apres appel par copy, le message est: "));
Serial.println(message);
Serial.println();
imprimeStringReference(message);
Serial.print(F("apres appel par reference, le message est: "));
Serial.println(message);
}
void loop() {} |
On peut voir dans ce qui est imprimé que dans la version avec duplication les adresse mémoire des instances sont différentes alors que par référence elles sont identiques
sur mon MEGA ça donne ceci en sortie:
adresse de message = 0x2DC <--- variable globale
adresse de unTexte en mode Copy = 0x21C8 <--- variable locale, duplication
Bonjour, T=0 ms
apres appel par copy, le message est: Bonjour, T=0 ms <--- et donc on n'a pas modifié la variable globale
adresse de unTexte en mode Reference = 0x2DC <--- on retrouve bien l'adresse de la variable globale
Bonjour, T=0 ms
apres appel par reference, le message est: au revoir <--- et donc on a modifié la variable globale
---
En aparté, il vaut mieux éviter d'utiliser la classe String si le programme doit tourner longtemps car toutes ces copies (surtout si la taille des Strings peut changer) risquent de faire des trous dans le tas et donc au bout d'un moment on risque de ne plus pouvoir allouer de la mémoire pour une nouvelle String
Partager