Recherche sur le blog

lundi 31 janvier 2011

[Web] PHP & Zend : Benchmark PDO vs Doctrine

Attardons-nous encore un moment dans les bases de données avec ce test de performances semblable au précédent, qui avait été réalisé durant mon travail de fin d'études (qui, au passage, a été écrit en anglais et en collaboration avec un ami). Ceci est un comparatif qui met face-à-face le PDO intégré à Zend Framework et Doctrine ORM.

Au début nous utilisions la méthode "select" du PDO mais nous avons bien sûr essayé la fonction qui exécute directement les requêtes codées en SQL (méthode "query", toujours fournie par Zend). Par la suite nous avons découvert l'ORM (Object Relational Mapper) répondant doux nom de "Doctrine", et nous nous sommes posé la question de savoir quel était le moyen le plus rapide pour l'exécution d'une requête. De plus, pour tester de manière plus approfondie, nous avons aussi manipulé le "DQL" qui signifie Doctrine Query Language, et dont la syntaxe ressemble vaguement à celle de la méthode "select" en Zend brièvement décrite ci-dessus.

Afin de comparer les différentes techniques, nous avons imaginé 4 scénarios :
  • Sélection de dix enregistrements.
  • Sélection de cent enregistrements.
  • Sélection de mille enregistrements.
  • Mise à jour d'un enregistrement au hasard parmi les enregistrements existants.
Dans notre cas les tests ont été effectués directement depuis le serveur (puisque le PHP est un langage qui s'exécute côté serveur). Ce serveur étant situé à Paderborn, en Allemagne. Puisque celui-ci est distant et que nous n'avions aucun contrôle, les valeurs pouvaient changer d'heure en heure selon les threads et autres tâches qui étaient en exécution. C'est pourquoi nous avons pris nos valeurs à différents moments de la journée, pour nous assurer de leur cohérence. Voici en complément la configuration matérielle de l'environnement:

Point de vue matériel: 
  • QEMU Virtual CPU version 0.11.0 à une fréquence de 2793.225 MHz avec2048 KB de cache. 
  • RAM virtuelle de 512 MB QEMU.
  • Harddisk version 0.11.0 QEMU.
Point de vue logiciel:
  • Apache/2.2.8 (Ubuntu) DAV/2.
  • SVN/1.4.6.
  • mod_python/3.3.1.
  • Python/2.5.2.
  • PHP/5.3.3-dev with eAccelerator 0.9.6-rc1.
  • MySQL version5.1.45-0.dotdeb.0.
Fonction de calcul du temps entre deux points

La fonction microtime en PHP permet de récupérer le temps en millisecondes. Ainsi, en exécutant la fonction avant et après, il est possible d'obtenir une valeur A et une valeur B. On soustrait A de B, pour obtenir C, qui est le temps d'exécution en millisecondes.

Tests effectués
  • Requête SQL avec l'adaptateur PDO.
  • Fonctions “Select” et “update” de Zend.
  • Requête DQL avec Doctrine 1.2.2.
  • Mapping d'objet avec Doctrine 1.2.2.
Les enregistrements présents dans la table ont tous le même contenu, avec une seule clé primaire (un ID). On a un entier comme clé primaire, un autre champ entier, un champ texte et un champ de type timestamp. La base de données est de type MySQL. Les temps seront, comme vous vous en doutez, exprimés en millisecondes.

Graphique global


Les plus petites valeurs sont les meilleures, cela s'entend. La première chose que l'on peut constater est que, tout en tenant compte des conditions de test et de la méthode employée pour réaliser celui-ci, Doctrine semble être le plus lent pour tout. Cela peut probablement provenir du fait qu'il y a deux couches qui viennent se rajouter au traditionnel PDO (qui est l'API de base pour interagir avec la base de données).

On peut effectivement lire dans la documentation officielle qu'il y a premièrement une couche appelée "Doctrine ORM" (la plus haute sur le schéma), chargée de créer un pont entre le modèle relationnel et le modèle objet. Sous celle-ci, on retrouve aussi la couche d'administration qui complète et étend la couche basique d'abstraction définie par le PDO.

Pour vous donner une idée de ce que cela peut donner lors d'une mise à jour, voici un graphique reprenant les moyennes de toutes les valeurs retenues, et ce pour les 4 techniques :


En conclusion, l'utilisation d'un ORM facilite grandement la tâche au développeur (puisque l'écriture des requêtes est simplifiée) mais risque de ralentir l'exécution de votre application web lorsque le nombre d'enregistrements est conséquent. Les créateurs de Doctrine promettaient une rapidité accrue avec la version 2, mais je n'ai pas encore eu l'occasion de la tester. Un jour, peut-être?

Références vers cet article :

[WinDev] Benchmark fonctions natives et requête SQL

Pendant mes heures de travail, j'ai réalisé une petite expérience que je souhaiterais approfondir par la suite mais cela dépendra évidemment du temps que je pourrais y accorder. En effet, celle-ci consiste tout simplement à tester les performances à la fois des fonctions natives à WinDev pour manipuler les bases de données telles que HyperFileSQL, ainsi que de la fonction qui permet d'exécuter une requête codée en SQL. J'avais déjà testé très rapidement le cas d'une mise à jour d'un seul enregistrement et bien sûr j'ai eu la brillante idée que de recommencer mais en gardant 10 valeurs, tout en tenant compte du trafic réseau éventuel.

Les conditions de test sont les suivantes :
  • Application WinDev tournant sur un HP ProBook 4720S, en réseau filaire 100 mbps. 
  • Connexion native à une machine IBM AS/400 (DB/2), elle aussi connectée en filaire.
  • Tranche horaire du test : 12h45 à 13h15, heures où normalement le réseau n'est pas trop surchargé.
Les deux cas testés sont :
  • Les fonctions "HModifie" (qui effectue une mise à jour dans une table) accompagnée de "HDésactiveFiltre" (qui désactive les filtres précédemment placés sur la table), "HTrouve" (qui renvoie un booléen si le record est trouvé) et "HLitPremier" (qui lit le premier résultat).

    Elles forment l'ensemble "HModifie". L'une des fonctions a un temps d'exécution de l'ordre de quelques microsecondes, sa valeur n'a donc pas été additionnée au total du temps pour ce cas. Attention toutefois, la fonction ne peut pas agir sur plusieurs enregistrements, donc à partir du moment où il faut boucler, la requête SQL pourrait prendre rapidement le dessus !
            
  • La fonction "HExecuteRequeteSQL" (qui lance une requête texte) accompagnée de "HAnnuleDéclaration" (qui libère les ressources allouées). Elles forment à elles deux l'ensemble "HExecuteRequeteSQL". Le critère de recherche choisi peut avoir impacté les performances.
Voici un graphique reprenant les dix valeurs retenues. Celles-ci ont été prises les unes à la suite des autres, durant la tranche horaire indiquée plus haut dans cet article. Les temps d'exécution sont exprimés en millisecondes et l'axe horizontal correspond au nombre d'appels effectués. Plus la valeur est petite, mieux c'est :


Selon les conditions de test, il semblerait que le fait d'exécuter directement une requête SQL de mise à jour plutôt que d'utiliser la fonction native de modification ralentisse l'exécution. Attention bien sûr, cela peut dépendre de l'index choisi dans la condition "where" de votre requête SQL! Dans chacun des cas testés, c'est ce que l'analyseur de performances WinDev nous a indiqué. Voici ce que donne la moyenne de toutes les valeurs réunies, pour chacun des deux cas :


L'utilisation de "HModifie" semblerait être bien plus rapide que le deuxième cas. Cela n'indique cependant pas à quelle échelle le ralentissement se produit (en cas de plusieurs enregistrements requérant une mise à jour, la fonction doit être répétée dans une boucle car celle-ci ne peut agir que sur une seule ligne à la fois, contrairement à une requête SQL. Il serait donc intéressant de tester les performances lorsqu'il s'agit de modifier plus d'un enregistrement à la fois !)

En conclusion, attention au choix de l'index pour réaliser votre requête SQL! Celle-ci peut amener à une mise à jour plus lente. Cependant, on conseille plus souvent d'utiliser ce type de requête malgré le fait que les fonctions natives soient optimisées pour ce genre de traitement.

dimanche 30 janvier 2011

[WinDev] Eléments de base du WLangage

Comme nous l'avons vu dans l'article précédent introduisant WinDev et tous ses outils, le WLangage est un langage de quatrième génération, ou encore "L4G". Ces langages sont appelés ainsi car ils sont développés principalement pour être utilisés en relation directe avec des systèmes de gestion de bases de données : en effet, ils intègrent des méthodes ainsi que la gestion des requêtes (en SQL par exemple) pour interagir avec ceux-ci.  WinDev possède donc son propre langage et l'environnement permet par exemple de créer des fenêtres dans lesquelles du code pourra être saisi.

 
Une des particularités du WLangage ? Celui-ci peut être saisi dans deux langues différentes : le français et l'anglais. Toutes les procédures en français (par exemple, iImprime) ont leur équivalent en anglais et du code copié/collé peut être directement retraduit par l'éditeur. Nous allons voir ensemble quelques éléments  de code assez basiques.

Déclarations de variables

Tout d'abord, rappelons les principes de base de la portée des variables. Celles-ci peuvent être globales (pour tout le projet) ou locales (à une fenêtre, par exemple, ou par rapport à une procédure). Lorsqu'une variable est globale, elle peut être accédée depuis n'importe quel endroit : une fenêtre, une procédure locale, une procédure globale... La déclaration ressemble à :

[nomVariable] est un(e) [type]

Ainsi, pour déclarer une chaîne ou un entier, il faut procéder de la manière suivante, et ce pour tous les autres types, tels que les tableaux ou les monétaires. Contrairement à beaucoup de langages, il n'existe pas de point-virgule pour délimiter la fin d'une ligne, et la charte de programmation de base impose, si elle est active, l'utilisation de préfixes :

sVarMaChaine est une chaîne
nVarIndice est un entier

Procédures et fonctions

Dans WinDev, il existe aussi bien des fonctions que des procédures. Les fonctions se différencient des procédures par le fait qu'elles renvoient un objet ou une valeur (d'un certain type), alors que les procédures ne le font normalement pas. Cependant, dans les versions actuelles de WinDev, elles peuvent aussi renvoyer une valeur ce qui permet désormais de ne plus utiliser le mot-clé "FONCTION".

PROCEDURE LP_maProcedure(param1, param2 = "valeur")
     ...
     RENVOYER Faux

Les paramètres des procédures ne sont pas typés, le type étant reconnu dynamiquement par l'éditeur et lors de la compilation. Des paramètres par défaut peuvent être définis, si on ne souhaite pas indiquer tous les paramètres à la fonction lors de l'appel. Cela devrait rappeler à certains les procédures du PL/SQL, dans Oracle.

Boucles et conditions

Il existe les mêmes conditions que dans beaucoup d'autres langages. Le célèbre "switch", que l'on utilise aussi bien en C ou en Java, apparait ici sous la forme d'un "SELON". La boucle "while" est remplacée par "TANTQUE", le "for" est lui remplacé par "POUR". Toutes les boucles et conditions se terminent par le mot-clé "FIN". Pour sortir prématurément d'une boucle, on peut aussi utiliser le mot-clé "SORTIR". 

SI (x = 0) ALORS
   // traitement
SINON
  // traitement sinon
FIN

Classes

La programmation orientée objet est aussi possible avec WinDev puisqu'on peut écrire des classes accompagnées de leurs procédures, objets, constructeurs... Lorsque l'on accède à une fonction d'un objet, il faudra écrire "monObjet.fonction()". Si l'on veut accéder à une propriété d'un objet créé, on utilisera plutôt "monObjet..propriété". Nous reviendrons sur ces éléments plus tard dans plusieurs autres articles. Les principes tels que l'encapsulation sont alors conservés !

Fonctions utiles
  • Info() : affiche une boite de dialogue avec un message d'information et un bouton OK.
  • OuiNon() : affiche une boite de dialogue avec une question et deux boutons : "Oui" et "Non".
  • Erreur() : affiche un message d'erreur Windows, qui est tout à fait personnalisable.
  • Bip : déclenche un son, pour signaler une erreur par exemple.
  • ...
Comme vous pouvez vous en apercevoir nous avons à faire à un langage très riche qui peut aussi être employé pour redéfinir des propriétés de champs (la couleur de fond, la taille, le contenu...),  effectuer des calculs, ou pour remplir des tables autrement qu'avec un fichier ou avec une requête. Nous verrons plus tard comment gérer le remplissage de celles-ci par programmation, ainsi que d'autres trucs et astuces !

[WinDev] En savoir plus...

A première vue, il pourrait s'agir d'un langage de programmation mais c'est bien plus que cela : WinDev, qui est développé par PC SOFT, est ce que l'on appelle couramment un "AGL" ou encore "Atelier de Génie Logiciel". Ces ateliers sont en fait un ensemble de plusieurs programmes qui permettent d'en créer d'autres, en offrant aux développeurs un lot très varié d'outils, pour gérer au mieux un projet. Ils permettent entre autres :
  • De gérer le budget d'un projet.
  • De gérer l'équipe et la répartition des tâches, ainsi que le temps passé sur ces tâches.
  • De créer des analyses UML (suivant le formalisme MERISE) : ce sont diverses sortes de diagrammes qui aident à la construction d'un projet. On retrouve des diagrammes qui représentent la séquence d'événements, les différents états dans lesquels l'application peut se trouver, les objets qui composent le futur programme, etc.
  • D'analyser les performances des applications créées.
  • De mettre en place des tests.
  • De documenter aisément chacune des parties d'un projet ou d'une applications.

On retrouve dans WinDev toutes ces fonctionnalités sous forme de différents sous-programmes dans la plupart des cas. De plus PC SOFT améliore chaque année WinDev et propose toujours plus de nouveautés. Ainsi, WinDev est un AGL qui comprend aussi son propre langage de programmation (le WLangage) de 4ème génération (qui est lié à un système de gestion de bases de données, ou "SGBD"), qui peut être écrit soit en anglais, soit en français, et peut être traduit dans les deux sens, et donc intègre son propre compilateur. On retrouve aussi des accès natifs à plusieurs SGBD, tels que Oracle, MySQL, ou même des bases de données tournant sur une machine IBM AS/400. 

Sans compter le designer de fenêtres, le générateur d'états, de requêtes, et la base de données "HyperFileSQL" qui est intégrée. Des "centres de contrôles" sont aussi fournis avec WinDev ou peuvent être téléchargés comme compléments afin de gérer chaque partie de cet environnement plus que complet !


PC SOFT a fait de WinDev l'AGL le plus répandu en France et distribué dans plus de 98 pays à travers le monde. Il ne faut donc pas sous-estimer celui-ci, et effectivement, il permet de développer 10 fois plus vite ! Le coup de pub n'était donc pas mensonger.