Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Pages: 1
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)
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
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:
Ce fameux élément qui est aussi long, c'est une multicheckbox avec 300 items
... $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
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???
Hors ligne
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.
Hors ligne
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
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)
Hors ligne
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é
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
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)
Hors ligne
En cherchant sur le net, j'ai vu que array_key_exists est 33% plus lent que isset !!
Hors ligne
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
Merci quand même.
Maintenant j'ai mon multi optimisé monolingue
Hors ligne
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
<?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
<?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
Hors ligne
Pages: 1