[PHP] Faut-il eviter de "boucler" si possible ?

Faut-il eviter de "boucler" si possible ? [PHP] - PHP - Programmation

Marsh Posté le 17-03-2010 à 02:47:21    

Bonsoir,

 

Bon voila, je cherche à faire du traitement de logs, les coloriser pour etre plus precis.
Je les recois sous la forme d'un tableau: une clé = une ligne de log.

 

Donc je cherche à les coloriser avec une répétition de "regles" de la sorte ( j'en ai un 20ene ):

 
Code :
  1. foreach ( $logs as $id => $log ) {
  2.  $log = preg_replace( '/bla bla/', "<span class=\"log_auth\">bla bla bla</span>", $log );
  3.  $log = preg_replace( '/bla bla 2/', "<span class=\"log_warn\">bla bla bla 2</span>", $log );
  4.  [...]
  5.  $log = preg_replace( '/bla bla 23/', "<span class=\"log_error\">bla bla bla 23</span>", $log );
  6.  
  7.  print $log;
  8. }
 

Je me suis dis que rajouter une boucle à l'interieur de la boucle pour eviter de matcher une ligne de log qui avait trouvée son occurence allait sensiblement me faire gagner en temps d'excecution, mais en faite non:

 
Code :
  1. foreach ( $logs as $id => $log ) {
  2.  $COLORIZE =  array();
  3.  $COLORIZE[] =  array( 'filter' => '/bla bla1/', 'css' => 'log_auth', 'replace' => 'bla bla1' );
  4.  $COLORIZE[] =  array( 'filter' => '/bla bla2/', 'css' => 'log_warn', 'replace' => 'bla bla2' );
  5.  [...]
  6.  $COLORIZE[] =  array( 'filter' => '/bla bla23/', 'css' => 'log_error', 'replace' => 'bla bla bla 23' );
  7.  
  8.  foreach ( $COLORIZE as $rule ) {
  9.    if ( preg_match( $rule['filter'] , $log )) {
  10.      $log = preg_replace( $rule['filter'], "<span class=\"".$rule['css']."\">".$rule['replace']."</span>", $log );
  11.      continue;
  12.     }
  13.  
  14.  print $log;
  15.  
  16. }
 

La premiere facon est plus rapide que la 2e ( sur 3000 lignes de log, il y a une difference de 0.05 secondes ).

 

J'ai aussi essayé de refaire la 1ere méthode avec une boucle:

 
Code :
  1. foreach ( $logs as $id => $log ) {
  2.  $COLORIZE =  array();
  3.  $COLORIZE[] =  array( 'filter' => '/bla bla1/', 'css' => 'log_auth', 'replace' => 'bla bla1' );
  4.  $COLORIZE[] =  array( 'filter' => '/bla bla2/', 'css' => 'log_warn', 'replace' => 'bla bla2' );
  5.  [...]
  6.  $COLORIZE[] =  array( 'filter' => '/bla bla23/', 'css' => 'log_error', 'replace' => 'bla bla bla 23' );
  7.  
  8.  foreach ( $COLORIZE as $rule ) {
  9. // Plus de test ni de continue, on en reviens a la 1ere méthode avec un foreach
  10.      $log = preg_replace( $rule['filter'], "<span class=\"".$rule['css']."\">".$rule['replace']."</span>", $log );
  11.     }
  12.  
  13.  print $log;
  14.  
  15. }
 

Cette méthode est la plus lente: + 0.13 seconde par rapport à la premiere.

 

Perso, je trouve que la 2e méthode est la plus élégante, mais est plus lente que la 1ere. Donc je me pose la question que j'ai énoncé dans le titre du topak: faut-il eviter les boucle si possible? :D

  


Message édité par ipnoz le 17-03-2010 à 02:48:34
Reply

Marsh Posté le 17-03-2010 à 02:47:21   

Reply

Marsh Posté le 17-03-2010 à 07:17:00    

ce n'est pas la boucle qui coute cher, mais le travail avec les expressions réugulières, ainsi que le chargement des données en mémoire  
essaye d'initialiser tes tableaux hors de la boucle  
et , sauf errreur de ma part, tu peux passer tes tableaux filter/css directement a preg_replace


---------------

Reply

Marsh Posté le 17-03-2010 à 07:44:58    

Ah bah oui, chui bête -_- .

 

J'ai sortis le tableau de la 1ere boucle, ca m'a fait gagné 0.07-0.08 seconde ce qui est deja mieux que la 1ere méthode.

 

De plus , je me suis trompé dans le 2e script:
continue; break;

 

Ce que je cherchais à faire à la base: si la regle est atteinte, on casse la boucle imbriquée histoire d'épargner des test sur la ligne de log avec le restant des filtres. Ca m'a fait gagner encore quelques FPS  [:nikolai]  .

 


Bref la fatigue, c'est pas bien.

 

Merci en tout cas  :hello:


Message édité par ipnoz le 17-03-2010 à 07:46:05
Reply

Marsh Posté le 23-03-2010 à 18:32:40    

Je te suggère d'utiliser preg_match() avec des tableaux aux lieu de chaines de caractères pour les masques, c'est plus rapide.
 
Et n'utilises preg_match() que si tu en as vraiment besoin, sinon strtr(), utilisée avec des tableaux, est beaucoup plus rapide (en plus d'être compatible utf-8).


---------------
Directeur Technique (CTO)
Reply

Marsh Posté le 23-03-2010 à 18:54:33    

CyberDenix a écrit :

strtr(), utilisée avec des tableaux, est beaucoup plus rapide (en plus d'être compatible utf-8).


 
non justement, c'est pas compatible

Reply

Sujets relatifs:

Leave a Replay

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