[PHP/MySQL] Wrappers MySQL - manque d'efficacité?

Wrappers MySQL - manque d'efficacité? [PHP/MySQL] - PHP - Programmation

Marsh Posté le 31-07-2006 à 16:52:23    

Salut,
 
JE me pose une question.
 
Je développe une appli Internet utilisant PHP/MySQL, et je me demande comment procéder pour gérer ma connexion et mes appels MySQL.
 
J'ai regardé ce qui se faisait un peu, et par exemple, j'ai regardé le code d'un forum (UseBB) qui utilise une casse "wrapper" autour de MySQL.
 
MAis j'en viens à me demander si c'est pas totalement inefficace.
 
Par exemple, voici le code qui est utilisé pour récupérer un résultata après requeête:
 

Code :
  1. function fetch_result(&$result) {
  2. return mysql_fetch_array($result, MYSQL_ASSOC);
  3. }


 
Est ce que ce genre de code ne risque pas de faire des copies de tableaux inappropriées? Je n'ai peut être pas une super expérience en Php, mais il me semble que sous PHP, la copie de tableau est "profonde", dans le sens où lorsqu'on copie un tableau, ce n'est pas qu'un référence qui est copiée mais la structure entière, ainsi que les données. Donc, si on récupère un gros resultset de notre requête MySQL, il risque d'y avoir du grabuge en terme de mémoire.
 
Est ce que je me trompe? Comment faire alors? Finalement, ne vaut il pas mieux coder des appels mysql directs au lieu d'utiliser une classe wrapper? (ou alors créer des fonctions retournant les valeurs par référence, mais c'est assez moche)?


Message édité par Yoyo@ le 31-07-2006 à 16:52:57
Reply

Marsh Posté le 31-07-2006 à 16:52:23   

Reply

Marsh Posté le 31-07-2006 à 16:58:50    

je ne sais pas si c'est trés util de coder une fonction pour en remplacer une... personnellement je trouve ça un peu limite. une fonction d'une ligne :sarcastic:..
 
maintenant en place mémoire, de toute façon pour afficher les résultats des requêtes.. tu sera bien obligé de passer par un mysql_fetch... donc de transférer ton résultat vers un tableau compréhensible en php.

Reply

Marsh Posté le 31-07-2006 à 17:04:04    

c'est de l'abstraction à son niveau le plus simple
 
avec ces fonctions d'une ligne on change de type de base en 5 minutes ;)
 
et je ne vois pas de copie dans le code indiqué (c'est un passage par référence)

Message cité 2 fois
Message édité par Sh@rdar le 31-07-2006 à 17:04:52

---------------
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 31-07-2006 à 17:07:02    

chani_t a écrit :

je ne sais pas si c'est trés util de coder une fonction pour en remplacer une... personnellement je trouve ça un peu limite. une fonction d'une ligne :sarcastic:..
 
maintenant en place mémoire, de toute façon pour afficher les résultats des requêtes.. tu sera bien obligé de passer par un mysql_fetch... donc de transférer ton résultat vers un tableau compréhensible en php.


 
Le code que je t'ai donné fait partie d'une class db.
 
Et ensuite, on aura un truc du genre:

Code :
  1. $result = $db->query("SELECT...." );
  2. $data = $db->fetch_result($result);


 
La classe est donc utilisée, mais au vu du code que je te donne plus haut, il me semble qu'il y a une copie de tableau qui me parait inutile. (retour de la méthode "fetch_result" )
 
Est ce que de faire la même chose en direct, et sans classe ne serait pas grandement plus efficace:

Code :
  1. $result = @mysql_query("SELECT...." ) or die(...);
  2. $data = mysql_fetch_array($result, MYSQL_ASSOC);


 
Ca évite quand même de copier le tableau, je me trompe?

Reply

Marsh Posté le 31-07-2006 à 17:09:16    

Sh@rdar a écrit :

c'est de l'abstraction à son niveau le plus simple
 
avec ces fonctions d'une ligne on change de type de base en 5 minutes ;)
 
et je ne vois pas de copie dans le code indiqué (c'est un passage par référence)


 
Bah justement, tu es certain que c'est un passage par référence?
 

Code :
  1. return mysql_fetch_array($result, MYSQL_ASSOC);


 
n'est il pas équivalent à:

Code :
  1. $tmparray = mysql_fetch_array($result, MYSQL_ASSOC);
  2. return $tmparray


 
C'est donc un retour par copie, non? (ici, on n'est pas en C/C++, dans lequel un tableau n'est qu'une adresse, un pointeur)


Message édité par Yoyo@ le 31-07-2006 à 17:09:31
Reply

Marsh Posté le 31-07-2006 à 17:09:46    

Sh@rdar a écrit :

..
avec ces fonctions d'une ligne on change de type de base en 5 minutes ;)


 
ben en même temps c'est pas beaucoup moins long que de tapper  $monresultat=mysql_fetch_array($result, MYSQL_ASSOC);.. c'est en ce sens que je doute de l'utilité... mais bon aprés c'est peut être une histoire d'habitudes.. ???

Reply

Marsh Posté le 31-07-2006 à 17:10:51    

chani_t a écrit :

ben en même temps c'est pas beaucoup moins long que de tapper  $monresultat=mysql_fetch_array($result, MYSQL_ASSOC);.. c'est en ce sens que je doute de l'utilité... mais bon aprés c'est peut être une histoire d'habitudes.. ???


 
si, si, c'est carrément utile, car tu peux avoir une gestion d'erreur plus fine, et occulter la gestion d'erreur du code appelant, lor de la connexion ou de l'exécution de requête.
 
Mais ce n'est vraiment pas ma question ici.
 
Je ne parle que de l'efficacité.


Message édité par Yoyo@ le 31-07-2006 à 17:11:31
Reply

Marsh Posté le 31-07-2006 à 17:12:57    

chani_t a écrit :

ben en même temps c'est pas beaucoup moins long que de tapper  $monresultat=mysql_fetch_array($result, MYSQL_ASSOC);.. c'est en ce sens que je doute de l'utilité... mais bon aprés c'est peut être une histoire d'habitudes.. ???


bin c'est à dire que le jour ou tu veux passer à postgre par exemple, t'es obligé de repasser dans tous tes scripts pour changer les appels aux fonctions mysql_* [:spamafote]
 
Et tant qu'a faire de l'abstraction, tu peux aussi utiliser des bibliothèques déjà prévues pour, genre AdoDB ...


Message édité par anapajari le 31-07-2006 à 17:13:28
Reply

Marsh Posté le 31-07-2006 à 17:15:58    

arf, c'est l'id de connection qui est passé par référence
 
j'ai un doute d'un coup, surtout qu'il me semble qu'il y a eu des changements avec les références au niveau des appels de fonction :/
 
faudrait que je revérifie mais là j'aurais pas le temps
 
(dans tous les cas ce genre d'abstraction est utile)


---------------
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 31-07-2006 à 17:21:46    

Sh@rdar a écrit :

arf, c'est l'id de connection qui est passé par référence
 
j'ai un doute d'un coup, surtout qu'il me semble qu'il y a eu des changements avec les références au niveau des appels de fonction :/
 
faudrait que je revérifie mais là j'aurais pas le temps
 
(dans tous les cas ce genre d'abstraction est utile)


 
Bah un mysql_fetch_array retourne un tableau.
 
Maitnenant, en PHP, les tableaux sont passés par "copie profonde". J'ai fait des tests avec PHP4 et PHP5, et c'est pareil.
 
Donc, en voyant ce genre de code, ça m'a fait bondir, tout en me disant "je ne dois pas être assez connaisseur donc, je vais poser la question".
 
Bien entendu que ce genre d'abstraction est utile, mais si ce que je dis est vrai, alors il peut y avoir un trop gros risque d'inefficacité lors du retour de gros jeux d'enregistrements.
 
Alors, quelqu'un pour confirmer ou infirmer?

Reply

Marsh Posté le 31-07-2006 à 17:21:46   

Reply

Marsh Posté le 31-07-2006 à 17:22:10    

Sh@rdar a écrit :

arf, c'est l'id de connection qui est passé par référence
 
j'ai un doute d'un coup, surtout qu'il me semble qu'il y a eu des changements avec les références au niveau des appels de fonction :/
 
faudrait que je revérifie mais là j'aurais pas le temps
 
(dans tous les cas ce genre d'abstraction est utile)


 
Ok... bon ba je verrais certainnement l'utilité de la chose quand je me serais plongé dans le PHP5 ;)

Reply

Marsh Posté le 31-07-2006 à 17:39:58    

Mine de rien, personne n'a répondu à ma question...
 
Finalement, elle se résume à ça:
 
En PHP, lorsqu'une fonction retourne un tableau, y a t'il copie du tableau ou passage par référence?

Reply

Marsh Posté le 31-07-2006 à 17:46:16    

Reply

Marsh Posté le 31-07-2006 à 17:49:42    


 
D'accord, je sais bien.
 
Donc, tu confirmes que le code que je donne plus haut,et pris du code d'un forum peut se révéler inefficace par rapport à un apel direct? Car il y a copie du tableau inutile?

Reply

Marsh Posté le 31-07-2006 à 18:06:41    

vite fait, de toute façon sur un pointeur MySQL si t'arrive à bourrer la mémoire sur une seule ligne, faut changer de langage :)
 
t'inquiète pas trop aux niveaux perfs pour ce genre de choses, y'a bien d'autres manières de plomber un script (sinon regarde pear ou adoDB)
 
sur ce bonne soirée :hello:


---------------
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 31-07-2006 à 18:07:29    

inéfficace j'aurais pas dit ça... Moins optimisé? je suis même pas sur vu que d'après la doc ( lien plus haut):

Citation :

N'utilisez pas  le retour par référence pour améliorer les performances, le moteur est suffisamment robuste pour optimiser cela en interne.


Mais rien ne t'empêche de te faire un petit benchmark hein!!!

Reply

Marsh Posté le 31-07-2006 à 18:20:36    

Merci pour ces précisions.
 
C'est tellement du langage "haut niveau" cette histoire qu'il vaut mieux que je n'essaie pas de comprendre ce qu'il se passe, et laisser les choses se faire tout seul (cf phrase plus haut).
 
Je vais donc continuer à utiliser mon wrapper, sans faire de retour par référence, et je vais faire confiance à l'otpimiseur ;) (tout en restant dubitatif)

Reply

Marsh Posté le 31-07-2006 à 18:38:33    

Après avoir lu plusieurs trucs sur le sujet (qui chiffonne toujours un adepte du C/Cpp)
 
je crois (par opposition à "je sais" ;)) que tous les passages de paramètres se font par copie et non par référence, même quand on utilise un & (ce qui peut paraître bizarre, voire totalement con, je suis d'accord^^)
 
 
En tout cas, après avoir cherché des infos un peu partout sur ce sujet, j'en suis arrivé à la conclusion que :
 
- php se démerde tout seul pour gérer la mémoire (alloc, desalloc, passage de var, etc...), même si ça me titille de foutre des unset() partout
- dans les cas extrêmes où ça rame trop je lance mon chronomètre en testant une/des autre(s) méthode(s) pour comparer, et j'utilise éventuellement des mysql_free_result() en cours de processus (sachant que le système fait lui aussi appel à cette fonction, mais uniquement en fin de processus)

Reply

Marsh Posté le 31-07-2006 à 18:45:16    

lkolrn a écrit :

Après avoir lu plusieurs trucs sur le sujet (qui chiffonne toujours un adepte du C/Cpp)


 
Copain ;)
 

lkolrn a écrit :


je crois (par opposition à "je sais" ;)) que tous les passages de paramètres se font par copie et non par référence, même quand on utilise un & (ce qui peut paraître bizarre, voire totalement con, je suis d'accord^^)


Euh... Bon, OK, je n'insiste pas! Y a tellement de choses qui se passent derrière les fagots que ça ne m'étonne qu'à moitié. Et alors, si c'est le cas, le passage par référence serait encore moins efficace que le passage par copie, car PHP se ferait "chier" à modifier toutes les occurrences d'une même référence lorsque l'une d'entre elles est modifiée.
 

lkolrn a écrit :


En tout cas, après avoir cherché des infos un peu partout sur ce sujet, j'en suis arrivé à la conclusion que :
 
- php se démerde tout seul pour gérer la mémoire (alloc, desalloc, passage de var, etc...), même si ça me titille de foutre des unset() partout
- dans les cas extrêmes où ça rame trop je lance mon chronomètre en testant une/des autre(s) méthode(s) pour comparer, et j'utilise éventuellement des mysql_free_result() en cours de processus (sachant que le système fait lui aussi appel à cette fonction, mais uniquement en fin de processus)


Bah disons que pour une appli web, ça ne ramera jamais vraiment en test unitaire, mais qu'ensuite, lorsque la cahrge monte va savoir où est ce que ton code n'est pas efficace.
Bref, je crois que PHP est le genre de langage où il faut coder sans trop savoir ce qui est fait par l'interprêteur, même si ça démange!
 
Merci pour les précisions.

Reply

Marsh Posté le 01-08-2006 à 00:10:33    

Bon, alors, pour info, j'ai lancé un bench dont voici le code:
 

Code :
  1. <?php
  2. list($usec, $sec) = explode(" ",microtime());
  3. $mt_start = (float)$usec + (float)$sec;
  4. for ($i=0; $i<10; $i++){
  5.  mysql_connect("localhost", "root", "" );
  6.  mysql_select_db("mydb" );
  7.  $result = mysql_query("SELECT * FROM facet" );
  8.  while($array = mysql_fetch_array($result, MYSQL_ASSOC)){
  9.  }
  10. }
  11. list($usec, $sec) = explode(" ",microtime());
  12. $elapsed = (float)$usec + (float)$sec - $mt_start;
  13. print "Elapsed: $elapsed";
  14. ?>


 
Donc, je lance un boucle de 10 itérations, sur une table de 140 000 enregistrements, avec 7 champs.
 
Résultat des courses:
 
Avec des appels à la main: 15.9s
Avec des appels en utilisant mon wrapper: 18.3s
 
Bref, la différence, même si elle existe, n'est pas non plus rédhibitoire, surtout que mes requêtes retoureront beaucoup moins de données.
 
Donc, ça vaut le coup d'utiliser un wrapper.
 
Maintenant, pour des applis lourdes, la différence es non négligeable (15.1%)
 
Voili...
 
:hello:


Message édité par Yoyo@ le 01-08-2006 à 09:19:06
Reply

Marsh Posté le 01-08-2006 à 00:14:31    

des applis lourdes qui bouclent 10 fois une ouverture de connexion et le parsing de 140 000 lignes sur la même page, je veux bien des exemples [:mlc]

Message cité 1 fois
Message édité par Sh@rdar le 01-08-2006 à 00:14:51

---------------
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 01-08-2006 à 00:19:25    

Sh@rdar a écrit :

des applis lourdes qui bouclent 10 fois une ouverture de connexion et le parsing de 140 000 lignes sur la même page, je veux bien des exemples [:mlc]


 
Bah disons qu'avec une grosse appli web, tu peux avoir plein d'accès concurrents, donc voilà, ça peut jouer...

Reply

Marsh Posté le 01-08-2006 à 00:25:23    

euh pour moi accés concurrents != requête lente ou script de 15 secondes


---------------
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 01-08-2006 à 07:22:55    

Mais peu importe!
 
Je l'ai fait sur une grosse requête pour avoir des temps significatifs.
 
Mais ce qui compte ici, c'est l'écart entre les deux méthodes. Ca sera pareil sur de petites requêtes.
 
Il faut bien trouver un moyen de benchmarker.

Reply

Marsh Posté le 01-08-2006 à 09:11:24    

Le principe d'un benchmark c'est d'être aussi près de la réalité que possible. Ton test, il ne vaut rien tel quel.

Reply

Marsh Posté le 01-08-2006 à 09:13:19    

on dirait le bench qui compare " et ' pour les string, sur 50 000 itérations c'est clair y'a un gain énorme, dans les faits si tu trouve un script qui est ralenti par ça tu me mp hein


---------------
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 01-08-2006 à 09:22:02    

Bah mon but était de comparer deux solutions techniques, donc, mon bench ne fait que les isoler.
 
Et sur cet aspect précis, on peut voir quel est le plus rapide dans l'absolu.
 
Ensuite, comme je le dis plus haut, mis dans un contexte normal, cette différence sera peu significative, sachant que la récupération de mes renregistrements ne représentera qu'une infime partie du processus entier.
Donc, voilà quoi.
 
Concernant la comparaison des " et ', par contre, par principe, si utiliser des ' ne rend pas mon code moins lisible et plus compliqué, alors j'utiliserais des ' au lieu de ". Pourquoi s'en priver?

Reply

Marsh Posté le 02-08-2006 à 09:12:39    

Je pense que la question est plus d'optimiser par des moyens faciles à mettre en oeuvre. c'est vrai que ça peut être intéressant de voir les methodes permettant de gagner des pouillémes, afin qu'en les associant, on puisse gagner un temps significatif. D'ailleurs, si vous avez des "trucs" concernant l'optimisation des temps de traitement je suis preneur...
 
;)

Reply

Marsh Posté le 02-08-2006 à 09:25:41    

Yoyo@ a écrit :


Concernant la comparaison des " et ', par contre, par principe, si utiliser des ' ne rend pas mon code moins lisible et plus compliqué, alors j'utiliserais des ' au lieu de ". Pourquoi s'en priver?


Tout simplement parce que ces différences de temps sont entièrement dépendantes de l'implémentation du moteur PHP. Si un jour un mec décide qu'il faut mettre le paquet sur les " plutôt que sur les ', ben toutes tes "optimisations" tombent à l'eau. Ca a déjà été le cas pour tout ce qui est du driver MySQL et gestion des itérateurs, donc ce n'est pas quelque chose d'exceptionnel.

Reply

Marsh Posté le 02-08-2006 à 10:30:46    

gizmo a écrit :

Tout simplement parce que ces différences de temps sont entièrement dépendantes de l'implémentation du moteur PHP. Si un jour un mec décide qu'il faut mettre le paquet sur les " plutôt que sur les ', ben toutes tes "optimisations" tombent à l'eau. Ca a déjà été le cas pour tout ce qui est du driver MySQL et gestion des itérateurs, donc ce n'est pas quelque chose d'exceptionnel.


 
Hmmmmm, alors là, je suis vraiment sceptique qu'un jour, les " puissent être plus rapide que les '
 
En effet, lorsque le parseur va rencontrer des ", il va chercher à détecter plein de choses, tels que les caractères échappés, les variables, etc...
Pour un simple ', il ne va chercher qu'éventuellement les \'.
 
Alors, si li'mplémentation du moteur PHP arrive à rendre des " plus efficaces que des ', c'est que c'est vraiment tordu.
 
Mais bon, je suis quand même d'accord avec toi sur le principe de se dire qu'on ne sait jamais lequel sera le plus efficace à l'avenir (ce qui est souvent le cas sur des langages haut niveau), mais je pense que le ' VS " est une exception.

Reply

Marsh Posté le 02-08-2006 à 10:55:17    

Oui enfin la différence entre les " et les ' est graduée en poils de cul de mouche hein. :o De plus, les différents optimiseurs PHP rendent complètement transparente l'utilisation de l'une ou l'autre syntaxe...

Reply

Marsh Posté le 02-08-2006 à 10:59:02    

soulmanto a écrit :

Oui enfin la différence entre les " et les ' est graduée en poils de cul de mouche hein. :o De plus, les différents optimiseurs PHP rendent complètement transparente l'utilisation de l'une ou l'autre syntaxe...


 
Grrrr, je n'ai jmais dit le contraire, mais comme je le dis plus haut, si utiliser des ' au lieu de " ne nuit pas à la lisibilité du code, alors même s'il s'agit d'un dixième de poil de moucheron, pourquoi s'en priver?
 
Bon, on clot ce débat stérile.
 
Y a une question plus intéressante de Chani_t plus haut.

Reply

Marsh Posté le 02-08-2006 à 11:04:55    

pour moi c'est du même acabit que d'indenter à X ou Y tabulations, faut que ça reste un choix en terme d'habitude / confort
 
pour l'optimisation bin y'a pas vraiment de recette miracle [:spamafote] (à part ne pas coder comme un porc des requêtes en boucle etc [:joce] )


Message édité par Sh@rdar le 02-08-2006 à 11:05:54

---------------
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 02-08-2006 à 11:09:31    

chani_t a écrit :

... D'ailleurs, si vous avez des "trucs" concernant l'optimisation des temps de traitement je suis preneur...


 
D'aillerus, tu entends quoi par "temps de traitement"?

Reply

Marsh Posté le 02-08-2006 à 11:11:32    

comme couche d'abstraction, y'a aussi PEAR:DB qui est pas mal...

Reply

Marsh Posté le 02-08-2006 à 11:13:50    

Yoyo@ a écrit :

D'aillerus, tu entends quoi par "temps de traitement"?


 
Temps de génération de page! ;)

Reply

Marsh Posté le 02-08-2006 à 11:16:11    

ba la même chose que ce qui semble être évident pour la pluspart d'entre vous... à savoir qu'un ', prendra moins de temps CPU qu'un "...
 
il semblerais que les boucle while soient préférable aux for (hein soul ! ;))... toujours pour gagner des µs...  sur des requêtes simple... voila tout ce qui peux, soit sur le serveur apache soit sur le serveur mysql, faire gagner du temps de traitement... donc générer plus rapidement des pages.
 
Parce que, pourquoi ne pas avoir tout de suite de bonnes habitudes ? hein ;)
 
EDIT : grillé par soul :D  [:anack]


Message édité par chani_t le 02-08-2006 à 11:20:28
Reply

Marsh Posté le 02-08-2006 à 11:44:47    

bah jusque la le seul truc significatif que j ai trouvé en optimisation de scripts c est ce qui concerne la bd : minimiser le nombre de connexions
du genre t es sur de faire plusieurs requetes sur une page tu les traites toutes avec une seule connexion j ai gagné pratiquement 50% en temps de generation avec ca
puis apres si t as des requetes complexes il faut bien optimiser ta table
y avait un lien interressant dans le topic des createurs de forums
http://hackmysql.com/case1
(interressant meme si j ai pas encore le niveau :D )
 
la c est de la vraie optimisation ou tu gagnes deja beaucoup en une seule iteration (et pas une µs sur 200 000 iterations quoi :/ )  
parce qu en "optimisant" ton php tu vas gagner que dalle ^^
 
enfin c est juste ce que j ai appris en lisant et en testant je suis encore bien noob et des gens avec plus d experience vont surement me demonter la face mais jusque la j y crois :D


Message édité par mIRROR le 02-08-2006 à 11:45:27
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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