Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 22-04-2008 10:25:19

Mr.MoOx
Administrateur
Lieu: Toulouse
Date d'inscription: 27-03-2007
Messages: 1444
Site web

[Résolu...][Zend_Form][1.5.1] Gros problème de performance

Bonjour à vous tous.

Je viens vous expliquer un problème qui me parait plu qu'aberrant.
Je dév un site d'annonce avec un moteur de recherche, rien de très compliqué.
J'utilise sur mon site le mvc, Zend_Layout  (donc quelques actions très simple - un menu, un form de login), Zend_Db enfin les composants essentiels quoi...

J'ai remarqué que la page où s'affiche mon moteur de recherche est très lente à s'afficher.
Et je me suis aperçu que Zend_Form provoque des lenteures plus qu'hallucinante...

Voici un petit comparatif de mes profiling avec xdebug:

Page d'accueil (l'action principale est vide et affiche juste "bonjour" - mais les actions statiques sont toutes appellés comme sur toutes mes pages)
http://tof.canardplus.com/preview2/0cf3a745-d055-4626-a823-68f364fa4c2f.png
La c'est un poil long mais ça va, c'est raisonnable.
Voici le profiling de la BD histoire que vous voyez bien que ça viens pas de la:

Exécution de 24 requêtes en 0.066657066345215 secondes
Temps moyen : 0.002777377764384 secondes
Requêtes par seconde: 360.05184920237 seconds
Requête la plus lente (secondes) : 0.0077140331268311
Requête la plus lente (SQL) : SELECT `places`.* FROM `places` ORDER BY `name` ASC
Temps de génération de la page :
1.2960119247437 (dont 0.066657066345215 pour la bd)

Et la la page avec mon formulaire
http://tof.canardplus.com/preview2/cd748a65-bcb7-4aef-b134-29941191c5cb.png

Exécution de 24 requêtes en 0.063480854034424 secondes
Temps moyen : 0.0026450355847677 secondes
Requêtes par seconde: 378.06674729022 seconds
Requête la plus lente (secondes) : 0.0063531398773193
Requête la plus lente (SQL) : SELECT `places`.* FROM `places` ORDER BY `name` ASC
Temps de génération de la page :
4.0126299858093 (dont 0.063480854034424 pour la bd)

En fouillant un peu dedans le profiling je tombe la dessus:
http://tof.canardplus.com/preview2/f2018f77-729e-4c8f-8620-3e6c9ad73f45.png
Ce fameux élément qui est aussi long, c'est une multicheckbox avec 300 items

Code:

...
$configForm = array(
            'id' => 'searchForm',
            'action'   => '/search/',
            'method'   => 'get',
            'elements' => array(
            ....
                'search_locations' => array('multicheckbox', array(
                    'label' => $this->tl->_('cities'),
                    'filters' => array('Int'),
                    'multiOptions' => $this->model->placesList //tableaux de 300valeurs avec id=>libelle,
                    'decorators' => array(
                        //array('ViewHelper', array('style'=>null)),
                        'ViewHelper',
                        array('HtmlTag', array('tag' => 'div','class' => 'cityChekboxList blockLabels')),
                        array('Label', array('tag' => 'h3')),
                        array('decorator' => array('div' => 'HtmlTag'), 'options' => array('tag' => 'div', 'id'=>'blockSelectedCities'))
                    )
                ))

Sur ma page vide mon dispatch prend 59ms, acceptable mais sur mon moteur, c'est 313ms!
La génération du formulaire prends pret de 130ms à lieu tout seul! Dont 93 pour l'élément ci dessus!
Dans mon form j'ai les éléments suivants:
- un double radio
- un double checkbox
- 5 checkboxs
- 2 champs text pour entier
- 2 autres champs text pour entier
- ma fameuse liste de 300 checkboxs
- 6 checkboxs
- 3 chekboxs indépendantes
- un champ texte

Rien d'énormeeee! Alors je pige pas.
Sur les perfs que vous voyez j'ai APC d'activé (sur Wamp, j'ai rien bidouillé je l'ai juste activé) et les perfs sont moins bonne. Sans APC pour ma page avec le moteur j'obtiens ça

Exécution de 24 requêtes en 0.17901611328125 secondes
Temps moyen : 0.0074590047200521 secondes
Requêtes par seconde: 134.06614387999 seconds
Requête la plus lente (secondes) : 0.045774936676025
Requête la plus lente (SQL) : DESCRIBE `places`
Temps de génération de la page :
3.6485450267792 (dont 0.17901611328125 pour la bd)

Donc presque 1/2 secondes de moins en moyenne...

J'ai pensé à mettre le form en cache mais le problème c'est que Zend_Form gère l'autoremplissage du form et si je met en cache ça ne marchera plus...

Et donc là je sais pas quoi faire sad
C'est résultat d'affichage sont inaceptable évidemment je comme à penser que Zend_Form est un peu (beaucoup?) lourd! C'est bien bête car c'est bien pratique...

Vous avez une idée, un conseil, des remarques??? big_smile

Hors ligne

 

#2 22-04-2008 10:52:14

nORKy
Membre
Date d'inscription: 06-03-2008
Messages: 1098

Re: [Résolu...][Zend_Form][1.5.1] Gros problème de performance

Peut etre que ca viens des décorateurs nombreux qui sont appelés.

As tu essayer de mettre un select ? (juste pour tester les performances)
Car, dans un select, les <option> ne sont pas décorés et donc gains de temps.


----
Gruiiik !

Hors ligne

 

#3 22-04-2008 14:38:02

Mr.MoOx
Administrateur
Lieu: Toulouse
Date d'inscription: 27-03-2007
Messages: 1444
Site web

Re: [Résolu...][Zend_Form][1.5.1] Gros problème de performance

Ca n'as pa l'air d'être ça... Je suis passé de 93ms pour le select à 91 sans decorateur... sad

Hors ligne

 

#4 23-04-2008 15:41:20

Mr.MoOx
Administrateur
Lieu: Toulouse
Date d'inscription: 27-03-2007
Messages: 1444
Site web

Re: [Résolu...][Zend_Form][1.5.1] Gros problème de performance

Bah non de dieu! Satané traduction automatique...

Le Zend_Form veut traduite tous mes champs... et fatalement quand je vois comment sont codés les tests pour l'existance de traduction, et que je sais que ce test est fait environ 400 fois, je comprends mieux!

C'est étrange car je ne spécifie pas de traducteur mais bon...
Je vais voir comment améliorer cela et je tiens au jus!

Hors ligne

 

#5 23-04-2008 16:04:45

nORKy
Membre
Date d'inscription: 06-03-2008
Messages: 1098

Re: [Résolu...][Zend_Form][1.5.1] Gros problème de performance

y'a pas moyen de désactiver la traduction ?
Ou au contraire de spécifier une traduction avec un tableau vide ? ((j'ai pas regardé le code))

Dernière modification par nORKy (23-04-2008 16:05:48)


----
Gruiiik !

Hors ligne

 

#6 23-04-2008 16:11:06

Mr.MoOx
Administrateur
Lieu: Toulouse
Date d'inscription: 27-03-2007
Messages: 1444
Site web

Re: [Résolu...][Zend_Form][1.5.1] Gros problème de performance

Le tableau vide est par defaut. Et il n'ya pas de moyen de désactiver car tous les tests se font dans tous les cas sur un tableau vide si y'a rien (ce qui est mon cas).
Voici la fonction (pour résumer) qui fait tout ramé

Code:

protected function _translateOption($option, $value)
    {
        if (!isset($this->_translated[$option])
            && (null !== ($translator = $this->getTranslator()))
            && $translator->isTranslated($value))
        {
            $this->options[$option] = $translator->translate($value);
            $this->_translated[$option] = true;
            return true;
        }

        return false;
    }

Ca parait peut etre pas méchant mais avec 400 valeurs c'est violent
En laissant juste "return false" je passe de 4s à 1.5s... Et là ça va être mieux car en fait je me fait mon propre multi, et je vire tout ce qui concerne la traduction (tous les tests passe à la trappe)
De plus les tests sont fait 2 fois: à la création du form, et au rendu ça fait 400*2...
Bref ça va le faire !

Hors ligne

 

#7 23-04-2008 16:20:04

nORKy
Membre
Date d'inscription: 06-03-2008
Messages: 1098

Re: [Résolu...][Zend_Form][1.5.1] Gros problème de performance

Et dans ce code, c'est quoi le plus lent ? isTranslated ??
Car, isTranslated, utilise des array_key_exists et je doute que cette fonction soit rapide.

$tab['a'] = 1;

quel différence il y a t-il entre
if (array_key_exists('a', $tab);
et
if (isset($tab['a']))

??
J'ai peur que array_key_exists boucle sur le tableau, alors que isset tente d'accéder directement à la valeur (ce qui serait plus rapide sur un tableu de 400)

Peut etre que je dis n'importe quoi , mais, c'est pt etre une idée à creuser..

Dernière modification par nORKy (23-04-2008 16:22:16)


----
Gruiiik !

Hors ligne

 

#8 23-04-2008 16:24:28

nORKy
Membre
Date d'inscription: 06-03-2008
Messages: 1098

Re: [Résolu...][Zend_Form][1.5.1] Gros problème de performance

En cherchant sur le net, j'ai vu que array_key_exists est 33% plus lent que isset !!


----
Gruiiik !

Hors ligne

 

#9 23-04-2008 16:25:58

Mr.MoOx
Administrateur
Lieu: Toulouse
Date d'inscription: 27-03-2007
Messages: 1444
Site web

Re: [Résolu...][Zend_Form][1.5.1] Gros problème de performance

Les tests s'arrêtent sur !isset($this->_translated[$option]) vu que le tableau est vide. J'ai pas cherché plus loin.
Du coup les array_key machin ne sont même pas appellés.
T'embette pas va, j'ai fais ce que je voulais smile
Merci quand même.
Maintenant j'ai mon multi optimisé monolingue big_smile

Hors ligne

 

#10 23-04-2008 16:58:52

Mr.MoOx
Administrateur
Lieu: Toulouse
Date d'inscription: 27-03-2007
Messages: 1444
Site web

Re: [Résolu...][Zend_Form][1.5.1] Gros problème de performance

J'ai trouvé cette méthode Zend_Form::setDisableTranslator(true); mais ça n'améliore pas grand chose.
Vu comment est codé l'element Multi, ça n'en tiens même pas compte.
Du coup jme suis codé ça (qui est en fait un copier coller en enlevant tou ce qui concerne la traduction)
Rx_Form_Element_Multi

Code:

<?php
/**
 * Rewix extension for Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://www.rewix.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to contact@rewix.com so we can send you a copy immediately.
 *
 * @category   Rx
 * @package    Rx_Form
 * @subpackage Element
 * @copyright  Copyright (c) 2007 Rewix (http://www.rewix.com)
 * @license    http://www.rewix.com/license/new-bsd     New BSD License
 */

/** Zend_Form_Element_Multi */
require_once 'Zend/Form/Element/Multi.php';

/**
 * multi-option form elements réécrit sans les options de traduction
 * En effet sur de gros lots, les test sont plus que mauvais pour les performances
 * Donc tout ce qui concerne la traduction est viré
 *
 * @category   Rx
 * @package    Rx_Form
 * @subpackage Element
 * @copyright  Copyright (c) 2007 Rewix (http://www.rewix.com)
 * @license    http://www.rewix.com/license/new-bsd     New BSD License
 */
abstract class Rx_Form_Element_Multi extends Zend_Form_Element_Multi
{
    /**
     * Retrieve options array
     *
     * @return array
     */
    protected function _getMultiOptions()
    {
        if (null === $this->options || !is_array($this->options)) {
            $this->options = array();
        }

        return $this->options;
    }

    /**
     * Add an option
     *
     * @param  string $option
     * @param  string $value
     * @return Zend_Form_Element_Multi
     */
    public function addMultiOption($option, $value = '')
    {
        $this->options[(string) $option] = $value;
        return $this;
    }

    /**
     * Add many options at once
     *
     * @param  array $options
     * @return Zend_Form_Element_Multi
     */
    public function addMultiOptions(array $options)
    {
        foreach ($options as $option => $value) {
            $this->addMultiOption((string)$option, (string)$value);
        }
        return $this;
    }

    /**
     * Retrieve single multi option
     *
     * @param  string $option
     * @return mixed
     */
    public function getMultiOption($option)
    {
        $option  = (string) $option;
        $this->_getMultiOptions();
        if (isset($this->options[$option])) {
            return $this->options[$option];
        }

        return null;
    }

    /**
     * Retrieve options
     *
     * @return array
     */
    public function getMultiOptions()
    {
        return $this->_getMultiOptions();
    }

    /**
     * Remove a single multi option
     *
     * @param  string $option
     * @return bool
     */
    public function removeMultiOption($option)
    {
        $option  = (string) $option;
        $this->_getMultiOptions();
        if (isset($this->options[$option])) {
            unset($this->options[$option]);
            return true;
        }

        return false;
    }

    /**
     * Clear all options
     *
     * @return Zend_Form_Element_Multi
     */
    public function clearMultiOptions()
    {
        $this->options = array();
        return $this;
    }
}

Et donc ça qui va avec
Rx_Form_Element_MultiCheckbox

Code:

<?php
/**
 * Rewix extension for Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://www.rewix.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to contact@rewix.com so we can send you a copy immediately.
 *
 * @category   Rx
 * @package    Rx_Form
 * @subpackage Element
 * @copyright  Copyright (c) 2007 Rewix (http://www.rewix.com)
 * @license    http://www.rewix.com/license/new-bsd     New BSD License
 */

/** Rx_Form_Element_Multi */
require_once 'Rx/Form/Element/Multi.php';

/**
 * MultiCheckbox form element
 *
 * Allows specifyinc a (multi-)dimensional associative array of values to use
 * as labelled checkboxes; these will return an array of values for those
 * checkboxes selected.
 *
 * @category   Rx
 * @package    Rx_Form
 * @subpackage Element
 * @copyright  Copyright (c) 2007 Rewix (http://www.rewix.com)
 * @license    http://www.rewix.com/license/new-bsd     New BSD License
 */
class Rx_Form_Element_MultiCheckbox extends Rx_Form_Element_Multi
{
    /**
     * Use formMultiCheckbox view helper by default
     * @var string
     */
    public $helper = 'formMultiCheckbox';

    /**
     * Separator to use between options; defaults to ''.
     * @var string
     */
    protected $_separator = '';

    /**
     * MultiCheckbox is an array of values by default
     * @var bool
     */
    protected $_isArray = true;
}

Si jamais ça peut aider un bourrin comme moi wink

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