/* Voici deux fonctions qui font la même chose: convertir un string en minuscules. Bien que n'adoptant pas le même mode opératoire, les deux fonctions ont en commun de parcourir la chaîne caractère par caractère, pour convertir le caractère en cours. */ #include <stdio.h> #include <string.h> // Pour strlen() #include <ctype.h> // Pour tolower() #include <sys/time.h> // Pour mesurer en microsecondes /* Fonction 1: convertit un string en minuscules */ void toLower1(char* s) { int i; for (i = 0; i < strlen(s); i++) s[i] = tolower(s[i]); } /* Fonction 2: convertit un string en minuscules */ void toLower2(char* s) { while (*s != '\0') { if (s[0]>64 && s[0]<91) s[0]+=32; s++; } } /* A première vue, les inconvénients de la fonction 1 sont: - déclarer un entier -> risque d' erreur si big string - appeller strlen() (qui reparcourt à son tour la chaîne!) - appeller tolower() d'ou inclusion de ctype.h -> conséquences: exe +gros, compilation +longue. Alors que la fonction 2 ne fait rien de tout ça. Cette dernière se sert du décalage de la valeur ASCII: A 65 Z 90 a 97 z 122 En ajoutant 32 à la valeur ASCII, elle obtient la transformation, (voir une table ASCII http://www.lookuptables.com/ ) c'est d' ailleurs ce que fait tolower() de ctype.h . Laquelle de ces deux fonctions est la plus rapide? Compiler avec gcc -Wall -s -O2 -o tolower tolower.c Lancer le test avec ./tolower Pour chacune des deux fonction, le main() - lance le chrono, - lance la fonction, - stoppe le chrono. */ int main() { char str1[255] = "uN teSt De STRing � ConVErtIr"; char str2[255] = "uN teSt De STRing � ConVErtIr"; struct timeval depart, fin; struct timezone tz; long duree=0; puts(str1); gettimeofday(&depart, &tz); toLower1(str1); // Appel fonction 1 gettimeofday(&fin, &tz); duree=(fin.tv_sec-depart.tv_sec) * 1000000L + (fin.tv_usec-depart.tv_usec); printf("Durée: %ld microsecondes\n", duree); puts(str1); puts(""); puts(str2); gettimeofday(&depart, &tz); toLower2(str2); // Appel fonction 2 gettimeofday(&fin, &tz); duree=(fin.tv_sec-depart.tv_sec) * 1000000L + (fin.tv_usec-depart.tv_usec); printf("Durée: %ld microsecondes\n", duree); puts(str2); return 0; } /* Ici la sortie console indique: uN teSt De STRing à ConVErtIr Durée: 11 microsecondes un test de string à convertir uN teSt De STRing à ConVErtIr Durée: 2 microsecondes un test de string à convertir Les deux font bien leur job, mais la fonction 1 est 5 fois plus lente que la fonction 2. Il semble qu'il vaut mieux se déplacer sur un pointeur plutôt que de grossir l'appli en incluant ctype.h pour appeler une fonction dont on n' a jamais vu le code. Vous avez certainement remarqué que dans la fonction 2, un test de condition est fait avant de convertir le caractère. Ajoutez ce test à la fonction 1 et remesurez: elle est deux fois plus rapide que sans le if! Mais toujours trois fois plus lente que la fonction 2. Toujours concernant ce test de condition, serait-il plus rapide s'il était noté if (s[0]>=65 && s[0]<=90) Plutôt que if (s[0]>64 && s[0]<91) Je ne sais pas. Il faudrait tester sur un très gros string pour en avoir des résultats significatifs. Inversez l' ordre d'appel des fonctions dans le main: peut-être que la première fonction appelée est désavantagée? Eh bien non! La Fonction 1 provient du School of Computing de l' université d'Utah: http://www.cs.utah.edu/contest/1997/takehome/C++/scan.cpp J'ai écrit la seconde fonction. Robin Masta - Aout 2006. */