Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Temps d'execution : theorie et pratique

26 réponses
Avatar
candide
Bonjour

J'ai codé selon deux algorithmes (le naïf et le "non naïf") un problème
classique (expliqué ci-après) et nécessitant de comparer des entiers. Le
naïf effectue 2*n comparaisons et le non naïf en effectue 25% de moins
(ie 1.5*n comparaisons). Les codes C sont simples et très similaires et
pourtant le naïf est plus rapide sur tous les tests que j'ai faits (et
pas qu'un peu : c'est de l'ordre de 50% plus rapide).

Le problème dont je parlais est le suivant : on a un tableau t de n
entiers et on veut retourner _à la fois_ le minimum et le maximum de t.

*) la méthode naïve consiste à parcourir t et
1) à comparer le minimum courant m de t à l'élément courant t[i] à
mettre à jour m si besoin
1) à comparer le maximum courant M de t à l'élément courant t[i] à
mettre à jour M si besoin
Cela fait 2 comparaisons d'entiers faites n fois donc 2*n comparaisons.
Cela fait aussi 2*n affectations au pire (en fait, n au pire).

*) la méthode astucieuse consiste à regrouper les éléments de t par
paires de deux éléments successifs, disons t[2*i] et t[2*i+1] puis
1) à comparer t[2*i] et t[2*i+1] ce qui permet de déterminer le plus
petit (mini) et le plus grand (maxi) des deux ;
2) à comparer le minimum courant m de t à mini et à mettre à jour m s'il
est "amélioré" ;
3) à comparer le maximum courant M de t à maxi et à mettre à jour M
s'il est "amélioré".
Cela fait 3 comparaisons faites n/2 fois donc 1.5*n comparaisons. Cela
fait aussi 2*n/2=n affectations au pire.


Voici le code C :


/* ==================== debut min_max_fclc.c ===================== */


#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void naif(int t[], int n, int *min, int *max)
{
int i;

int mini = t[0], maxi = t[0];

for (i = 0; i < n; i++)
{
if (t[i] < mini)
mini = t[i];
if (t[i] > maxi)
maxi = t[i];
}
*min = mini;
*max = maxi;
}

void non_naif(int *t, int n, int *min, int *max)
{
int mini = t[0], maxi = t[1];
int k = 0;

for (k = 0; k < n - 1; k += 2)
{
if (t[k] < t[k + 1])
{
if (t[k] < mini)
mini = t[k];
if (t[k + 1] > maxi)
maxi = t[k + 1];
}
else
{
if (t[k + 1] < mini)
mini = t[k + 1];
if (t[k] > maxi)
maxi = t[k];
}
}

*min = mini;
*max = maxi;
}

void test(int n)
{
int i;
int *t = malloc(n * sizeof *t);
int min, max;
clock_t now;

if (t != NULL)
{
/* Génération d'un tableau aléatoire */
srand(time(NULL));
for (i = 0; i < n; i++)
t[i] = rand();

/* Temps du naif */
now = clock();
naif(t, n, &min, &max);
printf("min=%d, max=%d\n", min, max);
printf("Temps CPU naif : %.2lf seconde.\n\n",

(double) (clock() - now) / CLOCKS_PER_SEC);


/* Temps du non naif */
now = clock();
non_naif(t, n, &min, &max);
printf("min=%d, max=%d\n", min, max);
printf("Temps CPU non naif : %.2lf seconde.\n",

(double) (clock() - now) / CLOCKS_PER_SEC);
free(t);
}
}


int main(void)
{
/* je suppose n pair pour simplifier le code de non_naif() */
test(1 << 26);
return 0;
}

/* ==================== fin min_max_fclc.c ===================== */


Voici la compilation et l'exécution :

$ gcc -O2 -W -Wall -std=c99 -pedantic -o x min_max_fclc.c
$ ./x
min=9, max=2147483640
Temps CPU naif : 0.28 seconde.

min=9, max=2147483640
Temps CPU non naif : 0.44 seconde.
$


Qui pourrait m'expliquer pourquoi le premier code est pas loin de 50%
plus rapide que le second alors que ce dernier effectue 25% de moins de
comparaisons et pas plus d'affectations (et qu'il n'y a rien d'autre
comme opérations, par exemple le nombre d'instructions if est moindre
dans le 2ème algo que dans le premier) ?

6 réponses

1 2 3
Avatar
rixed
On 2009-10-24, Marc Espie wrote:
bref, je ne comprend pas pourquoi ce type de technologie n'est pas sortie
des labos.



Oui mais n'est-ce pas contradictoire de se plaindre de ce que ces
nouvelles technos restent cantonnées aux labos plutot que d'être
intégrées aux compilateurs C ? N'est ce pas plutôt désolant que
nous restions cantonnés au C ?
Avatar
Erwan David
écrivait :

On 2009-10-24, Marc Espie wrote:
bref, je ne comprend pas pourquoi ce type de technologie n'est pas sortie
des labos.



Oui mais n'est-ce pas contradictoire de se plaindre de ce que ces
nouvelles technos restent cantonnées aux labos plutot que d'être
intégrées aux compilateurs C ? N'est ce pas plutôt désolant que
nous restions cantonnés au C ?



T'as pas lu le début du message...

Les langages prétendus plus évolués n'apportent *rien* de ce point de
vue. Juste des tonnes de bibliothèques et de frameworks indigestes dont
l'accumulation rend la lecture et la maintenance du code quasi
impossible...


--
Le travail n'est pas une bonne chose. Si ça l'était,
les riches l'auraient accaparé
Avatar
rixed
On 2009-10-31, Erwan David wrote:
Les langages prétendus plus évolués n'apportent *rien* de ce point de
vue. Juste des tonnes de bibliothèques et de frameworks indigestes dont
l'accumulation rend la lecture et la maintenance du code quasi
impossible...



Quelle genre de sclérose peut bien nous faire passer C# et java pour
les dernières technos sorties des labos ?

Il existe des langages qui font plus sérieusement avancer le schmilblick
; par exemple haskell, ML... Pourquoi ne décidons nous pas de les mettre
davantage en pratique ?
Avatar
espie
In article ,
wrote:
On 2009-10-31, Erwan David wrote:
Les langages prétendus plus évolués n'apportent *rien* de ce point de
vue. Juste des tonnes de bibliothèques et de frameworks indigestes dont
l'accumulation rend la lecture et la maintenance du code quasi
impossible...



Quelle genre de sclérose peut bien nous faire passer C# et java pour
les dernières technos sorties des labos ?

Il existe des langages qui font plus sérieusement avancer le schmilblick
; par exemple haskell, ML... Pourquoi ne décidons nous pas de les mettre
davantage en pratique ?



Pour haskell, faudrait qu'il existe une implementation decente.
Je suis d'assez pres ce qui s'y passe, entre autres grace aux
commentaires de Mathias Kilian qui essaie desesperement de tenir a jour
le portage sur OpenBSD. Tant que les mecs upstream seront des gros cons,
ca n'ira pas tres vite...

cote ML, lequel ? SML ? ocaml ?

Mais bon, comme Erwan l'a dit, tu es a cote de la plaque. La question n'est
pas de pondre un n-eme langage a peine utilise (pour ca, smalltalk suffisait
amplement. Essaie de te renseigner et de voir pouquoi c'est d'autres langages
qui l'ont supplante, il y a 20 ans). La question est plus de travailler sur
ce qui existe, et est utilise, et voir comment l'ameliorer.

Le meme de "ce qui existe est de la merde, refaisons tout a partir de rien"
presente un seul defaut: difficile d'obtenir l'adhesion d'une large partie
du public... c'est pas parce que c'est difficile d'ameliorer un langage
procedural tel que C que ca ne presente pas un interet certain...
Avatar
Pierre Maurette
Marc Espie, le 24/10/2009 a écrit :
In article ,
Pierre Maurette wrote:

Sinon, je suis assez impressionné par les optimisations mises en place
par le compilo Microsoft. Sur un bench /à-la-con/ je ne suis jamais
parvenu à faire un truc rapide que MSVC.



C'est facile de faire un compilo rapide quand tu mets des oeilleres.
Typiquement, MSVC a deux avantages par rapport a, par exemple, gcc:
- un seul processeur cible



Bien entendu, je suis d'accord. Je n'ai aucun engagement ni politique
ni moral par rapport à *LA POLEMIQUE*.
Bien entendu, on sera toujours plus efficace quand on détermine à
priori la plateforme.
C'est d'ailleurs assez marrant, j'utilise massivement des Unix - en
fait des Linux - et je regarde un peu comment ça fonctionne.
Mon paysage à moi que j'aime bien, où je me sens à l'aise, c'est
aujourd'hui Seven, après pour quelques mois encore XP Pro x64. J'avais
plusieurs machines, qui aujourd'hui roupillent, la planète, toussa.
J'ai remplacé tout le bordel par des VM. Alors j'ai un paquet de Debian
qui tournent en serveur, tout se passe bien. Et puis quelques desktop
Linux, et c'est là où je pige moins. Puppy, pourquoi pas. Debian, je
veux bien. Mais Ubuntu, je ne comprends pas. Ça marche relativement
bien. Mais c'est quoi ce truc qui fonctionne sur plateforme x86-32 et
après moulte péripéties x86-64, et rien d'autre, tout en prenant sa
substantifique moelle chez Debian, avec des sources compilables sur les
machines les plus exotiques ?

Alors après, on peut critiquer. On peut regretter. Mais je ne vois pas
pourquoi vouer aux gémonies un des compilateurs gratuits - si ce n'est
libre - le plus performant.

--
Pierre Maurette
Avatar
Erwan David
écrivait :

On 2009-10-31, Erwan David wrote:
Les langages prétendus plus évolués n'apportent *rien* de ce point de
vue. Juste des tonnes de bibliothèques et de frameworks indigestes dont
l'accumulation rend la lecture et la maintenance du code quasi
impossible...



Quelle genre de sclérose peut bien nous faire passer C# et java pour
les dernières technos sorties des labos ?

Il existe des langages qui font plus sérieusement avancer le schmilblick
; par exemple haskell, ML... Pourquoi ne décidons nous pas de les mettre
davantage en pratique ?



Hummm ML est plus veux que Java et C#, hein...


--
Le travail n'est pas une bonne chose. Si ça l'était,
les riches l'auraient accaparé
1 2 3