Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 28-08-2007 18:39:03

rod
Administrateur
Lieu: Tours
Date d'inscription: 01-03-2007
Messages: 97
Site web

[Zend_Db][*.*.*] Evitez d'utiliser la méthode factory()

Bonjour,

J'ai effectué quelques tests sur un serveur local. Pour savoir quelle méthode de connexion à un serveur MySQL avec l'utilisation du driver PDO était la plus performante :

  * PDO()
  * Zend_Db::factory()
  * Zend_Db_Adapter_Pdo_Mysql();

Les résultats sont assez logiques et évident.

L'utilisation de PDO() et Zend_Db_Adapter_Pdo_Mysql() est pratiquement équivalente sauf qu'avec le package du Framework vous pouvez utiliser l'ORM. Donc un gain de temps en terme de productivité.

Par contre Zend_Db::factory() met 10 fois plus de temps à s'éxécuter. Il faut donc éviter d'utiliser cette méthode. De toute façon lorsqu'un projet est bien pensé vous connaissez le serveur de données et le pilote à utiliser. J'exclus évidement le développement d'un CMS qui doit pouvoir s'adapter aux conditions de productions.

Mon post n'est pas très exhaustif car il existe d'autres méthodes pour se connecter à MySQL et il existe d'autres SGBD comme SQL Server, PostgreSQL, SQLite, etc.

Mais maintenant c'est à vous de voir. L'important dans n'importe quel projet est l'analyse et peu importe l'outil utilisé ou la méthode d'analyse utilisé.

Consultez le manuel pour voir comment se connecter en utilisant Zend_Db_Adapter_Pdo_Mysql()

Hors ligne

 

#2 28-08-2007 20:04:17

2mx
Membre
Lieu: Grenoble
Date d'inscription: 06-08-2007
Messages: 125

Re: [Zend_Db][*.*.*] Evitez d'utiliser la méthode factory()

Merci pour l'info, mais whaou 10 fois plus de temps pour Zend_Db::factory() ça me parait énorme pour le simple fait d'utiliser une factory.

Hors ligne

 

#3 28-08-2007 20:37:07

rod
Administrateur
Lieu: Tours
Date d'inscription: 01-03-2007
Messages: 97
Site web

Re: [Zend_Db][*.*.*] Evitez d'utiliser la méthode factory()

Ca doit varier un peu d'un serveur à l'autre mais même si c'était 3 fois plus c'est trop énorme comme différence pour que ça soit intéressant à utiliser.

Hors ligne

 

#4 28-08-2007 21:11:28

2mx
Membre
Lieu: Grenoble
Date d'inscription: 06-08-2007
Messages: 125

Re: [Zend_Db][*.*.*] Evitez d'utiliser la méthode factory()

rod a écrit:

Ca doit varier un peu d'un serveur à l'autre mais même si c'était 3 fois plus c'est trop énorme comme différence pour que ça soit intéressant à utiliser.

Je ne conteste pas ton teste, mais si effectivement il y a un énorme écart, comment le justifier ?
Même 2 fois plus de temps me paraitrait étrange, au vu des traitements qu'effectue Zend_Db::factory() je m'attendrait plutôt à quelques micros secondes.

Bon, après tout, tout est relatif entre 1ms et 2ms on double le temps d'exécution mais ramené au temps total d'exécution de 100ms d'un script l'impact est presque nul.

Hors ligne

 

#5 28-08-2007 23:37:35

rod
Administrateur
Lieu: Tours
Date d'inscription: 01-03-2007
Messages: 97
Site web

Re: [Zend_Db][*.*.*] Evitez d'utiliser la méthode factory()

On parle bien là de micro-secondes mais sur un site à fort trafic ça peut avoir des conséquences assez énorme.

Sachant que normalement tu sais quel pilote tu as besoin pour te connecter à ton serveur de bases de données. Donc tu peux éviter d'utiliser le factory.

Hors ligne

 

#6 29-08-2007 09:49:06

sekaijin
Membre
Date d'inscription: 17-08-2007
Messages: 1137

Re: [Zend_Db][*.*.*] Evitez d'utiliser la méthode factory()

comme toujours l'abstraction à un contre point en terme de perf.

et il ne convient de l'utiliser qu'à bon escient

un conseil tout de même si vous ne l'utilisez pas. restez assez proche de ce que produirait le factory car on ne sais jamais comment évolue une application et un changement de moteur de base de donnée n'est pas à exclure.


donc si votre code est assez générique le changement se fera sans trop de difficultés.

mais 10 fois je suis assez étonné. car avant ZF en php j'avais écrit un package d'abstraction de base de données qui gérait le mapping Objet-Relationnel et mes perf était de 1,05 1,1 entre passer de l'intenciation directe à l'inctentiation au travers du package.

10 c'est vraiment beaucoup.
A+JYT

Hors ligne

 

#7 29-08-2007 12:07:39

rod
Administrateur
Lieu: Tours
Date d'inscription: 01-03-2007
Messages: 97
Site web

Re: [Zend_Db][*.*.*] Evitez d'utiliser la méthode factory()

Suite à un e-mail voici la méthode utilisée :

Le fichier pdo.php

Code:

<?php

$dsn = 'mysql:host=localhost;dbname=test';
$user = 'root';
$password = '';

try {
    $time = microtime();
    $db = new PDO($dsn, $user, $password);
    $time = microtime() - $time;
    echo '<p>' . $time . ' secs avec <code>PDO();</code></p>';
} catch (Exception $e) {
    die($e->getMessage());
}

Le fichier zend.db.php

Code:

<?php

set_include_path(realpath('../library'));
require_once 'Zend/Db.php';
$params = array(
    'host' => 'localhost',
    'dbname' => 'test',
    'username' => 'root',
    'password' => ''
);

try {
    $time = microtime();
    $db = Zend_Db::factory('pdo_mysql', $params);
    $db->getConnection();
    $time = microtime() - $time;
    echo '<p>' . $time . ' secs avec <code>Zend_Db::factory();</code></p>';
} catch (Zend_Db_Adapter_Exception $e) {
    die($e->getMessage());
}

Le fichier zend.db.adpater.mysql.php

Code:

<?php

set_include_path(realpath('../library'));
require_once 'Zend/Db/Adapter/Pdo/Mysql.php';
$params = array(
    'host' => 'localhost',
    'dbname' => 'test',
    'username' => 'root',
    'password' => ''
);

try {
    $time = microtime();
    $db = new Zend_Db_Adapter_Pdo_Mysql($params);
    $db->getConnection();
    $time = microtime() - $time;
    echo '<p>' . $time . ' secs avec <code>Zend_Db_Adapter_Pdo_Mysql();</code></p>';
} catch (Zend_Db_Adapter_Exception $e) {
    die($e->getMessage());
}

Suffit ensuite d'executer un à un les fichiers et cela plusieurs fois. Puis de faire une moyenne pour chaque cas d'utilisation. Je sais ce n'est pas très automatisé.

Hors ligne

 

#8 29-08-2007 12:59:59

sekaijin
Membre
Date d'inscription: 17-08-2007
Messages: 1137

Re: [Zend_Db][*.*.*] Evitez d'utiliser la méthode factory()

il te faudrait charger toi même les classes dans le temps mesuré
car zend_db factory utilise le chargement de la classe adéquate dans son code donc tu ne mesure pas exactement la même chose.

A+JYT

Hors ligne

 

#9 29-08-2007 13:18:49

rod
Administrateur
Lieu: Tours
Date d'inscription: 01-03-2007
Messages: 97
Site web

Re: [Zend_Db][*.*.*] Evitez d'utiliser la méthode factory()

En fait le temps que prennait le chargement de la classe ne m'interessait pas donc je n'ai pas souhaité l'inclure. Mais après je voulais donner ici une piste seulement et pas une façon de faire.

Maintenant à vous de tester et de choisir la solution qu'il vous faut.

Hors ligne

 

#10 29-08-2007 17:43:47

2mx
Membre
Lieu: Grenoble
Date d'inscription: 06-08-2007
Messages: 125

Re: [Zend_Db][*.*.*] Evitez d'utiliser la méthode factory()

Je viens de faire un petit teste avec l'outil de benchmark apache ab (http://httpd.apache.org/docs/2.0/programs/ab.html) en simulant 100 requêtes consécutives sur un serveur de dev (Celeron 434.33 MHz, apache2, php 5.2.3, Mysql 5.0)

Les temps d'exécution total sont les suivants :

* 11.594021 seconds avec la Zend_Db::factory
* 10.916688 seconds avec Zend_Db_Adapter

Avec un écart de 0.68 seconds  Zend_Db::factory est 1,06 fois plus lent.

Maintenant je n'ai pas l'habitude de travaillé sur des sites soumis à forte charge et ne sais pas quoi dire de ces chiffres.

Hors ligne

 

#11 29-08-2007 18:39:06

sekaijin
Membre
Date d'inscription: 17-08-2007
Messages: 1137

Re: [Zend_Db][*.*.*] Evitez d'utiliser la méthode factory()

rod a écrit:

En fait le temps que prennait le chargement de la classe ne m'interessait pas donc je n'ai pas souhaité l'inclure. Mais après je voulais donner ici une piste seulement et pas une façon de faire.

Maintenant à vous de tester et de choisir la solution qu'il vous faut.

justement lorsque tu fais ton test avec Factory tu inclus le chargement de la classe puisque le factory charge la classe adéquate.

donc si tu veux comparer il te faut inclure le chargement de tes classe dans le comparatif

c'est comme si tu voulais comparer la vitesse d'une ferari avec celle d'une 2CV et que pour la ferari tu inclus le temps de faire le plein d'essence alors que pour la 2CV tu ne compte que le temps de parcours.

tes résultats sont incohérents c'est tout

A+JYT

Hors ligne

 

#12 29-08-2007 18:49:19

rod
Administrateur
Lieu: Tours
Date d'inscription: 01-03-2007
Messages: 97
Site web

Re: [Zend_Db][*.*.*] Evitez d'utiliser la méthode factory()

La comparaison avec la voiture est fausse.

Je verrai plutot comparer le temps que tu mettrais à aller directement à ta voiture et le temps que mettrais un portier à aller chercher la voiture sachant qu'avant il faut qu'il récupère tes clés, qu'il trouve la bonne, ensuite qu'il aille chercher la voiture et qu'il te la rammene.

Du coup le résultat final est le même mais toi tu connais déjà la solution alors que le portier devant faire quelques tests pour trouver la bonne clé et aller chercher ta voiture.

Donc si je comparerai cette situation c'est comme si je devais faire abstraction du temps que le portier mettrai à trouvé ma clé et aller chercher ma voiture.  Le calcul de la différence serai faussé. Car le portier fera tout de même tout ces tests.

Hors ligne

 

#13 29-08-2007 21:18:28

sekaijin
Membre
Date d'inscription: 17-08-2007
Messages: 1137

Re: [Zend_Db][*.*.*] Evitez d'utiliser la méthode factory()

non de non ce n'est pas ça
le test tel qu'il à été fait c'est comparer le temps que te mets pour passer la grille de ton hôtel lorsque tu es devant  ta voiture et celui cumulé ou tu demande d'abord au maître d'hôtel que te la récupérer.

dans le cas de

Code:

    $time = microtime();
    //ma voiture est là et je démare
    $db = new Zend_Db_Adapter_Pdo_Mysql($params);
    //je passe la grille
    $db->getConnection();
    $time = microtime() - $time;

tu n'inclus pas le temps de charger la classe Zend_Db_Adapter_Pdo_Mysql alors que dans

Code:

    $time = microtime();
    // ma voiture n'est pas là je demande au maître d'hôtel, j'attends et je démarre enfin
    $db = Zend_Db::factory('pdo_mysql', $params);
    //je passe la grille
    $db->getConnection();
    $time = microtime() - $time;

ce temps est présent puisque le factory charge la classe

donc pour effectuer la bonne mesure soit tu fait

Code:

    $time = microtime();
    //ma voiture est là et je démare
    $db = new Zend_Db_Adapter_Pdo_Mysql($params);
    $db->getConnection();
    $time = microtime() - $time;

et

Code:

    Zend_Loader::load('Zend_Db_Adapter_Pdo_Mysql');
    $time = microtime();
    // je demande au maître d'hôtel qui me dit que ma voiture est là je démarre
    $db = Zend_Db::factory('pdo_mysql', $params);
    $db->getConnection();
    $time = microtime() - $time;

la classe étant chargé le factory n'a pas à le faire

soit tu fait le contraire

Code:

    $time = microtime();
    // ma voiture n'est pas là je vais la chercher
    Zend_Loader::load('Zend_Db_Adapter_Pdo_Mysql');
    // je démarre
    $db = new Zend_Db_Adapter_Pdo_Mysql($params);
    $db->getConnection();
    $time = microtime() - $time;

et

Code:

    $time = microtime();
    // ma voiture n'est pas là je demande au maître d'hôtel qui me l'apporte et je démarre.
    $db = Zend_Db::factory('pdo_mysql', $params);
    $db->getConnection();
    $time = microtime() - $time;

dans ce cas tu compte le temps de chargement dans les deux.

il ne s'agit pas là de quelque tests il n'est pas question d'aller la chercher sachant ou ne sachant pas où elle se trouve.
dans ton premier cas la voiture est déjà là et dans le deuxième elle n'y est pas et tu passe par un intermédiaires pour la récupérer

A+JYT

Dernière modification par sekaijin (29-08-2007 21:23:58)

Hors ligne

 

Pied de page des forums

Propulsé par PunBB
© Copyright 2002–2005 Rickard Andersson
Traduction par punbb.fr

Graphisme réalisé par l'agence Rodolphe Eveilleau
Développement par Kitpages