calculer le pourcentage rapidement ?

calculer le pourcentage rapidement ? - C - Programmation

Marsh Posté le 29-06-2007 à 11:10:06    

Bonjour,

 

j'aimerai savoir quelle est la meilleure manière de calculer un pourcentage d'une boucle qui s'effectue, moi je fais, par exemple pour afficher tout les 5% :

 
Code :
  1. int percents;
  2. for (i=0;i<N;i++) {
  3. // code ...
  4.   if ( (percents = (int)floor(100.*i/N))%5 == 0) {     
  5.         printf("%d\r",percents);
  6.         fflush(stdout);
  7.    }
  8. }
 


comment faire mieux ?

 

merci par avance  :jap:


Message édité par in_your_phion le 29-06-2007 à 11:10:59
Reply

Marsh Posté le 29-06-2007 à 11:10:06   

Reply

Marsh Posté le 29-06-2007 à 11:45:38    

quel intérêt ? c'est ça qui bouffe ton CPU, c'est évident.
Par contre, si tu vires ton floor et ton calcul flottant, t'as une chance de rendre ton code bitable.

Reply

Marsh Posté le 29-06-2007 à 11:58:43    

Taz a écrit :

quel intérêt ? c'est ça qui bouffe ton CPU, c'est évident.
Par contre, si tu vires ton floor et ton calcul flottant, t'as une chance de rendre ton code bitable.

 

salut
oui je sais que c'est nul. si tu as des suggestions ... :jap:

 

j'ai fait ça qui est un peu mieux :

 
Code :
  1. for (i=0;i<N;i++) {
  2. // ...
  3. if (i%(N/20) == 0) {
  4.    printf("%d\r",i*100/N);
  5.    fflush(stdout);
  6. }
  7. }
 

mais toujours le modulo

Message cité 1 fois
Message édité par in_your_phion le 29-06-2007 à 13:04:25
Reply

Marsh Posté le 29-06-2007 à 22:30:13    

in_your_phion a écrit :

mais toujours le modulo


Ben c'est obligé. Si t'as n opérations à traiter et que tu veux afficher une info toutes les p opérations, tu seras obligé de faire un truc qui ressemble à
si ((operation_en_cours modulo p) == 0)
    afficher(info)

Message cité 1 fois
Message édité par Sve@r le 29-06-2007 à 22:30:30

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 29-06-2007 à 23:45:25    

Sve@r a écrit :

Ben c'est obligé. Si t'as n opérations à traiter et que tu veux afficher une info toutes les p opérations, tu seras obligé de faire un truc qui ressemble à
si ((operation_en_cours modulo p) == 0)
    afficher(info)


 
salut,
d'accord. Mais je pensais que le modulo c'etait 'gourmand'

Reply

Marsh Posté le 30-06-2007 à 07:57:59    

in_your_phion a écrit :

salut,
d'accord. Mais je pensais que le modulo c'etait 'gourmand'


Pas plus qu'une division...


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 30-06-2007 à 09:14:09    

A priori, si t'as besoin d'un indicateur de progression, c'est que le calcul que tu veux surveiller prend un peu plus de temps qu'une poignee de divisions ... tu peux toujours faire un masque, sinon (ce qui revient a faire des modulos par des puissances de deux)

Reply

Marsh Posté le 30-06-2007 à 21:55:38    

bord, si tu veux aller vite, il te faut faire un modulo sur une puissance de deux.Sinon c'est lourd a calculer.
 
Ensuite, disont tous les 0x01<<n tours de boucle, tu calcule le pourcentage et tu l'affiche. La tu peut te faire plaisir, car ca ne s'execute pas souvent et le test est leger.

Reply

Marsh Posté le 02-07-2007 à 10:01:54    

deadalnix a écrit :

bord, si tu veux aller vite, il te faut faire un modulo sur une puissance de deux.Sinon c'est lourd a calculer.

 


merci pour vos réponses,

 

pourquoi sur une puissance de deux ?

 
Code :
  1. for (i=0;i<N;i++) {
  2. if (i%1024 == 0) {
  3.       printf("%d\r",i);
  4.       fllsh(stdout);
  5.   }
  6. }
 

comme ça ?? Quelle puissance de deux faut-il prendre ? :o


Message édité par in_your_phion le 02-07-2007 à 10:05:50
Reply

Marsh Posté le 02-07-2007 à 10:12:14    

du coup ça plus de pourcentage ni rien. tu veux que ça soit rapide ? vire tout.

Reply

Marsh Posté le 02-07-2007 à 10:12:14   

Reply

Marsh Posté le 02-07-2007 à 10:20:44    

Taz a écrit :

du coup ça plus de pourcentage ni rien. tu veux que ça soit rapide ? vire tout.


 
lol, oui je veux que ce soit rapide mais quand même que ca affiche le pourcentage!
 
je voulais dire comme ca :
 

Code :
  1. for (i=0;i<N;i++) {
  2.    if (i%1024 == 0) {
  3.        printf("%d\r",i*100/N);
  4.        fflush(stdout);
  5.        }
  6. }


 

Reply

Marsh Posté le 02-07-2007 à 10:37:46    

nul. choisi à quel interval tu veut afficher un %. ensuite calcule l'interval, et suit le.

Reply

Marsh Posté le 02-07-2007 à 10:38:27    

'tain mais quand est-ce que j'arreterais de perdre du temps sur ce genre de topic ...

Reply

Marsh Posté le 02-07-2007 à 10:43:14    

Taz a écrit :

'tain mais quand est-ce que j'arreterais de perdre du temps sur ce genre de topic ...

 

heu t'es pas obligé de choisir d'en perdre hein, mais j'imagine que toi aussi tu as été débutant en C un jour, donc tu dois savoir que c'est bien sympa quand on trouve de l'aide :)


Message édité par in_your_phion le 02-07-2007 à 10:45:32
Reply

Marsh Posté le 02-07-2007 à 10:48:39    

Taz a écrit :

nul. choisi à quel interval tu veut afficher un %. ensuite calcule l'interval, et suit le.


 
alors ca revient à ce que j'avais proposé au début avec les N/20, non ?

Reply

Marsh Posté le 02-07-2007 à 15:19:46    

in_your_phion a écrit :

alors ca revient à ce que j'avais proposé au début avec les N/20, non ?


Ben oui. Après tout, un intervalle régulier n'est rien de plus qu'une division...


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 02-07-2007 à 16:49:24    

Sve@r a écrit :

Ben oui. Après tout, un intervalle régulier n'est rien de plus qu'une division...


 
ok :o
 
merci bien!  :jap:

Reply

Marsh Posté le 02-07-2007 à 18:36:46    

Une division ou un modulo d'une puissance de deux est peut se féaire tres rapidement via un masque pour le modulo et un decalage pour la division.
 
Donc c'est ce qu'il te reste de plus legers pour faire ce calcul.
 
une division par un autre nombre peut devenir tres lourde, et par un nombre variable ne pourra pas etre optimisée via le compilo.

Reply

Marsh Posté le 02-07-2007 à 19:04:19    

J'ai juste une question...
 
Le ratio entre ce que consomme un printf afin de convertir un decimal en chaîne de caractère, et un bête calcul de division (pourquoi faire en float, t'es à 0,00001% près ?) il est pas de 1 pour 1000 ?
 
Si tu veux vraiment optmiser, évite déjà de faire un printf("%d",val);...


Message édité par MagicBuzz le 02-07-2007 à 19:04:49
Reply

Marsh Posté le 02-07-2007 à 19:09:24    

Personne n'a pense a ca ?  
 

Code :
  1. int step = N / 20;
  2. int next_percent = 0;
  3. int percents = 0;
  4. for (i=0;i<N;i++)
  5. {
  6. // code ...
  7.   if(i == next_percent)
  8.   {
  9.       printf("\r%d",percents);
  10.       fflush(stdout);
  11.       next_percent += step;
  12.       percents += 5;
  13.   }
  14. }

Message cité 1 fois
Message édité par Ace17 le 02-07-2007 à 19:10:10
Reply

Marsh Posté le 02-07-2007 à 19:13:35    

Ah, c'est malin ca ^^. Un comparaison ca va au moins aussi vite qu'un modulo ou une division via puissance de 2, mais la c'est vachement plus souple :P

Reply

Marsh Posté le 02-07-2007 à 19:15:34    

Ace17 a écrit :

Personne n'a pense a ca ?


La même sans printf("%d" ); et on est copains :D
 
Un array de 20 lignes.
Avec 0%, 5%, 10%, ...
 
Un percents++ au lieu du += 5
Et un printf(prct[percents]); à la place.
 
A mon avis, là ouais, on peut parler d'optimisation réelle non ?
 
Je maintiens ma question...
 
Pour que printf convertisse 0x0F en "15" il lui faut combien de cycles comparé à un a/b (avec a et b des entiers)

Reply

Marsh Posté le 02-07-2007 à 19:38:10    

On s'en fout, ce code ne sera executé que 20 fois, c'est pas la ou il faut chercher une optimisation.

Reply

Marsh Posté le 02-07-2007 à 19:50:19    

C marrant en tout cas, en C# la méthode de Ace17 reste plus rapide que ma méthode... D'un autre côté un array de string en C# c'est pas tout à fait aussi simple à gérer qu'en C++... Fait refaire le test avec des substr pour voir :D

Reply

Marsh Posté le 02-07-2007 à 19:50:53    

deadalnix a écrit :

On s'en fout, ce code ne sera executé que 20 fois, c'est pas la ou il faut chercher une optimisation.


A oui c'est vrai autant pour moi :jap: C'est au niveau du if () que ça pêche... Pas réveillé moi :D
 
M'enfin quand même, en passant à un string et des substr (pour se rapprocher légèrement de la gestion en mémoire du C++ qui va avoir un pointeur se baladant le long du array), j'arrive à gagner près de 10%  :D
 
En tout cas, dans les deux cas, ça va 6 fois plus vite :)


Message édité par MagicBuzz le 02-07-2007 à 19:59:07
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed