[PHP] comparatif vitesse strtr(), str_replace() et preg_replace()

comparatif vitesse strtr(), str_replace() et preg_replace() [PHP] - PHP - Programmation

Marsh Posté le 28-11-2002 à 16:32:42    

Salut,
 
Voilà, je me suis fait un petit comparatif de ces trois fonctions afin de déterminer laquelle serait la plus appropriée à l'usage que je voulais en faire.
 
J'ai pensé que les résultats pourraient en intéresser d'autres, alors je vous les mets ici.
 
http://freekill.free.fr/brols/comparatif.png
 
Le texte utilisé était composé de

Code :
  1. ":) "

, qui devaient être transformés en tags <img> affichant le smiley correspondant. (comme c'est original :D)
 
L'array de recherche/remplacement comportait 45 éléments.
 
Le test a été réalisé avec plusieurs taille de texte et un nombre différent de passes sur le texte (qui restait inchangé).
 
Il a été exécuté 100 fois et les valeurs que vous voyez dans le graphique sont les moyennes obtenues.
 
J'espère que vous trouverez ça utile?


---------------
Faux & usage de faux ¤ Machins roses ¤ ASCIImage ¤ HFR Enhance v0.8.6
Reply

Marsh Posté le 28-11-2002 à 16:32:42   

Reply

Marsh Posté le 28-11-2002 à 17:58:56    

thx pour cette petite étude  :jap:  
les perfs de str_replace augmentent sur un texte comportant plusieurs fois la même valeur à remplacer.
 
A savoir aussi : un remplacement de tag (uniformes) dans un texte long est encore plus performant en appliquant un  algorithme de découpage en tableau du texte.
ex :  
"voici un texte contenant des {TIG} et encore des {TAG}, puis des {TOG}"
 
après découpage en tableau avec explode() on obtient dans le tableau :
$tab[0]['str']= 'voici un texte contenant des ';
$tab[0]['key']= 'TIG';
$tab[1]['str']= ' et encore des ';
$tab[1]['key']= 'TAG';
$tab[2]['str']= ', puis des ';
$tab[2]['key']= 'TOG';
 
dans un autre tableau à accès par clé, on a les valeurs à remplacer:
$replace['TIG']= 'un tag';
$replace['TAG']= 'un tag 2';
$replace['TOG']= 'un tag 3';
 
on remplace en parcourant le tableau contenant le texte
for ($i=0, $max= count($tab); $i<$max; $i++){
  $texte.= $tab[$i]['str']. $replace[$tab[$i]['key']];
  //on peut aussi décider de ce qui sera fait avec les clés non trouvées
}
 
ça arrache bien surtout si le texte est grand (voir les système de templates les plus performants).


Message édité par ethernal le 30-11-2002 à 12:47:20

---------------
...oups kernel error...
Reply

Marsh Posté le 28-11-2002 à 18:07:03    

Freekill a écrit a écrit :

Salut,
 
J'espère que vous trouverez ça utile?




 
En effet, c'est bien sympa  [:xp1700]


---------------
Informaticien.be - Lancez des défis à vos amis
Reply

Marsh Posté le 28-11-2002 à 18:09:12    

d'un autre coté le résultat était prévisible :o

Reply

Marsh Posté le 28-11-2002 à 18:15:41    

Bah un joli chart ca fait tjs plaisir pour comparer, continue seulement  :)


---------------
Informaticien.be - Lancez des défis à vos amis
Reply

Marsh Posté le 28-11-2002 à 18:21:09    

en clair strtr is the best :)

Reply

Marsh Posté le 28-11-2002 à 18:22:47    

chacal_one333 a écrit a écrit :

en clair strtr is the best :)




plus rapide ne veut pas dire le meilleur, sinon les autres ne seraient pas la  [:sinclaire]  
les expressions regulieres c'est bien pratique, même si dans ce cas c'est la solution la plus lente.

Reply

Marsh Posté le 28-11-2002 à 18:27:40    

lorill a écrit a écrit :

 
plus rapide ne veut pas dire le meilleur, sinon les autres ne seraient pas la  [:sinclaire]  
les expressions regulieres c'est bien pratique, même si dans ce cas c'est la solution la plus lente.



toute info est bonne a prendre :)

Reply

Marsh Posté le 28-11-2002 à 18:30:29    


Par contre j'ai un doute la... strtr  c'est pour remplacer un char par un autre, donc comment tu remplacer :) par une img avec ca?
 
Ou alors j'ai mal lu la doc
 
http://www.php.net/strtr  
 
Non  :??:


---------------
Informaticien.be - Lancez des défis à vos amis
Reply

Marsh Posté le 28-11-2002 à 18:36:26    

C'est sûr que pour faire des remplacement simples, les expressions régulières font un peu GROSSE CAVALERIE.
 
Cela dit, je ne pensait pas que preg_replace() serait si mal placée. Mais c'est sans doute en grande partie due au fait qu'avec preg_replace() t'est obligé de boucler en php sur le tableau.


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 28-11-2002 à 18:36:26   

Reply

Marsh Posté le 28-11-2002 à 18:38:13    

Zion a écrit a écrit :

 
Par contre j'ai un doute la... strtr  c'est pour remplacer un char par un autre, donc comment tu remplacer :) par une img avec ca?
 
Ou alors j'ai mal lu la doc
 
http://www.php.net/strtr  
 
Non  :??:  




 
Si, tu peut ne passer que 2 argument dont le 2ème est un tableau des remplacement à faire, non pas sur des char simple mais sur des strings !
 
C'est pour çà qu'strtr() est si rapide. Un seul appel suffit.


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 28-11-2002 à 18:52:15    

Mara's dad a écrit a écrit :

 
 
Si, tu peut ne passer que 2 argument dont le 2ème est un tableau des remplacement à faire, non pas sur des char simple mais sur des strings !
 
C'est pour çà qu'strtr() est si rapide. Un seul appel suffit.




 
Ah oki  :jap:  
 


---------------
Informaticien.be - Lancez des défis à vos amis
Reply

Marsh Posté le 28-11-2002 à 18:52:37    

:??:  :??:  
perso je vois pas l'intêret de faire un comparo de fonctions qui n'ont à priori pas le même but..
 
ça semble limpide que les regexp sont utiles uniquement pour des règles de remplacement / recherche un minimum complexe, ce qui explique leurs performances
 
pour un remplacement simple str_replace() et strtr() sont déjà plus étudièes


---------------
La musique c'est comme la bouffe, tu te souviens du restaurant dans lequel t'as bien mangé 20 ans plus tôt, mais pas du sandwich d'il y a 5 minutes :o - Plugin pour winamp ©Harkonnen : http://harko.free.fr/soft
Reply

Marsh Posté le 29-11-2002 à 12:31:16    

pour ceux que ça interesse, j'avais aussi fait kks tests de perfs sur d'autres fonctions.
 
D'une part sur la tokenization d'une chaine de caracteres, et d'autre part sur le trim :
 


explode        : 1.2373288869858
strtok         : 0.89884400367737
substr+strpos  : 2.9062099456787
 
trim           : 0.27045500278473
rtrim          : 0.26708698272705
ltrim          : 0.37658405303955


 
testé avec php 4.3.0rc2, le test tourne 500K fois et le temps indiqué est en secondes.


---------------
Don't blink. Don't even blink. Blink and you're dead. They are fast, faster than you could believe, don't turn your back, don't look away, and DON'T BLINK. Good luck.
Reply

Marsh Posté le 29-11-2002 à 12:43:40    

six_dfx a écrit a écrit :

pour ceux que ça interesse, j'avais aussi fait kks tests de perfs sur d'autres fonctions.
 
D'une part sur la tokenization d'une chaine de caracteres, et d'autre part sur le trim :
 


explode        : 1.2373288869858
strtok         : 0.89884400367737
substr+strpos  : 2.9062099456787
 
trim           : 0.27045500278473
rtrim          : 0.26708698272705
ltrim          : 0.37658405303955


 
testé avec php 4.3.0rc2, le test tourne 500K fois et le temps indiqué est en secondes.
 




 
Ouais OK, m'enfin les chaînes sur lesquelles tu fais explode() ou strtok(), elles sont longues de combien de caractères ? Et quel est le délimiteur ? Et y a combien d'occurrences du délimiteur ?
Pis sinon, pourquoi t'as pas testé split() ?
Idem pour les trim(), quelle est le type de chaîne, y a combien d'espaces en début, en fin, etc...


---------------
Everyone thinks of changing the world, but no one thinks of changing himself  |  It is the peculiar quality of a fool to perceive the faults of others and to forget his own  |  Early clumsiness is not a verdict, it’s an essential ingredient.
Reply

Marsh Posté le 29-11-2002 à 12:44:53    

Sh@rdar a écrit a écrit :

 :??:  :??:  
perso je vois pas l'intêret de faire un comparo de fonctions qui n'ont à priori pas le même but..
 
ça semble limpide que les regexp sont utiles uniquement pour des règles de remplacement / recherche un minimum complexe, ce qui explique leurs performances
 
pour un remplacement simple str_replace() et strtr() sont déjà plus étudièes
 




 
Pour voir si les avantages valent la perte de vitesse.
 
Par exemple preg_replace()est la seule qui permet de limiter le nombre de remplacements effectués, les autres sont case sensitive, etc.
 
De plus je disposais d'assez peu d'infos sur les perfs de strtr(), surtout depuis que cette fonction accepte les arrays comme arguments.


---------------
Faux & usage de faux ¤ Machins roses ¤ ASCIImage ¤ HFR Enhance v0.8.6
Reply

Marsh Posté le 29-11-2002 à 12:51:38    

bin justement non, puisque logiquement, ton choix de fonction se fait avant tout sur ta règle de remplacement dont tu as besoin
 
faudrait mieux comparer les regexp avec ou sans case sensitive, et les fonctions strXXX selon la longueur du remplacement à effectuer, ça serait déjà plus parlant..


Message édité par Sh@rdar le 29-11-2002 à 12:52:09

---------------
La musique c'est comme la bouffe, tu te souviens du restaurant dans lequel t'as bien mangé 20 ans plus tôt, mais pas du sandwich d'il y a 5 minutes :o - Plugin pour winamp ©Harkonnen : http://harko.free.fr/soft
Reply

Marsh Posté le 29-11-2002 à 12:54:26    

Sh@rdar a écrit a écrit :

 
faudrait mieux comparer les regexp avec ou sans case sensitive, et les fonctions strXXX selon la longueur du remplacement à effectuer, ça serait déjà plus parlant..




 
je t'en prie? :D


---------------
Faux & usage de faux ¤ Machins roses ¤ ASCIImage ¤ HFR Enhance v0.8.6
Reply

Marsh Posté le 29-11-2002 à 13:04:37    

six_dfx a écrit a écrit :


explode        : 1.2373288869858
strtok         : 0.89884400367737
substr+strpos  : 2.9062099456787






 
comment tu as fait ton test ?
strtok() a bien été exécuté x fois pour obtenir le même tableau que celui obtenu par 1 explode() ?
 
si oui, je crois que je vais modifier mon générateur de templates...


---------------
...oups kernel error...
Reply

Marsh Posté le 29-11-2002 à 14:57:02    

Taiche a écrit a écrit :

 
 
Ouais OK, m'enfin les chaînes sur lesquelles tu fais explode() ou strtok(), elles sont longues de combien de caractères ? Et quel est le délimiteur ? Et y a combien d'occurrences du délimiteur ?
Pis sinon, pourquoi t'as pas testé split() ?
Idem pour les trim(), quelle est le type de chaîne, y a combien d'espaces en début, en fin, etc...




 
J'ai fait tous les tests sur les mêmes chaines (délim = ":", longueur dans les 50 bytes, 2 tokens donc 1 occurence du délimiteur, peut etre que explode est + interessant quand on monte en nombre de tokens)
 
split est un alias pour explode() il me semble c'est la raison pour laquelle je l'ai laissé de côté ...
 
[citation]
comment tu as fait ton test ?  
strtok() a bien été exécuté x fois pour obtenir le même tableau que celui obtenu par 1 explode() ?  
[/citation]
 
oui, 2 appels a strtok contre 1 a explode()


Message édité par six_dfx le 29-11-2002 à 14:58:35

---------------
Don't blink. Don't even blink. Blink and you're dead. They are fast, faster than you could believe, don't turn your back, don't look away, and DON'T BLINK. Good luck.
Reply

Marsh Posté le 29-11-2002 à 14:58:04    

six_dfx a écrit a écrit :

 
split est un alias pour explode() il me semble c'est la raison pour laquelle je l'ai laissé de côté ...
 




 
 
 :non:  
 
split() gère les regexp, pas explode()


---------------
La musique c'est comme la bouffe, tu te souviens du restaurant dans lequel t'as bien mangé 20 ans plus tôt, mais pas du sandwich d'il y a 5 minutes :o - Plugin pour winamp ©Harkonnen : http://harko.free.fr/soft
Reply

Marsh Posté le 29-11-2002 à 15:00:07    

Sh@rdar a écrit a écrit :

 
 
 
 :non:  
 
split() gère les regexp, pas explode()




 
ooops ...
 
confondu avec join() et implode()  :jap:


---------------
Don't blink. Don't even blink. Blink and you're dead. They are fast, faster than you could believe, don't turn your back, don't look away, and DON'T BLINK. Good luck.
Reply

Marsh Posté le 29-11-2002 à 15:02:29    

jcomprend rien [:dawa]

Reply

Marsh Posté le 29-11-2002 à 15:02:46    

six_dfx a écrit a écrit :

 
 
J'ai fait tous les tests sur les mêmes chaines (délim = ":", longueur dans les 50 bytes, 2 tokens donc 1 occurence du délimiteur, peut etre que explode est + interessant quand on monte en nombre de tokens)
 
split est un alias pour explode() il me semble c'est la raison pour laquelle je l'ai laissé de côté ...
 
 
 
oui, 2 appels a strtok contre 1 a explode()
 




 
Effectivement, je pense qu'il serait bon d'augmenter le nombre de tokens. Genre 6 ou 7, ça commencerait à être bien représentatif. Non pas que je sois un fervent admirateur de la fonction explode() mais c'est juste pour avoir des résultats pertinents :)
D'ailleurs, si t'as pas le temps de faire les tests, j'peux les faire, faut juste me dire :)


---------------
Everyone thinks of changing the world, but no one thinks of changing himself  |  It is the peculiar quality of a fool to perceive the faults of others and to forget his own  |  Early clumsiness is not a verdict, it’s an essential ingredient.
Reply

Marsh Posté le 29-11-2002 à 15:11:58    

Si ça interesse quelqu'un qui voudrait lui aussi un bon moyen de tester les perfs de diverses fonctions php, voila comment j'ai procédé :
 

Code :
  1. function mtime() {
  2.         $a=explode(" ", microtime());
  3.         return($a[0]+$a[1]);
  4. }
  5. function proctest($proc, $arg=false, $loops=1000) {
  6.         $stime=mtime();
  7.         for ($a=0;$a<$loops/5;++$a) {
  8.                 $proc($arg);
  9.                 $proc($arg);
  10.                 $proc($arg);
  11.                 $proc($arg);
  12.                 $proc($arg);
  13.         }
  14.         $etime=mtime();
  15.         return($etime-$stime);
  16. }
  17. function p_explode($v) {
  18.         $s=explode(":", $v);
  19.         $a=$s[0];
  20.         $b=$s[1];
  21. }
  22. function p_strtok($v) {
  23.         $a=strtok($v, ":" );
  24.         $b=strtok("" );
  25. }
  26. function p_strpos($v) {
  27.         $p=strpos($ps, ":" );
  28.         $a=substr($ps, 0, $p);
  29.         $b=substr($ps, $p);
  30. }
  31. $s="Connection: keep-alive\n";
  32. $l=100000;
  33. echo "p_explode : ".proctest("p_explode", $s, $l)."\n";
  34. echo "p_strtok  : ".proctest("p_strtok", $s, $l)."\n";
  35. echo "p_strpos  : ".proctest("p_strpos", $s, $l)."\n";


---------------
Don't blink. Don't even blink. Blink and you're dead. They are fast, faster than you could believe, don't turn your back, don't look away, and DON'T BLINK. Good luck.
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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