Bienvenue, Invité. Veuillez vous connecter ou vous enregistrer.
Avez-vous perdu votre courriel d'activation?
20 Mars 2010, 00:29:50

Connexion avec identifiant, mot de passe et durée de la session
Accueil Aide Recherche Identifiez-vous Enregistrez-vous
forum.mangue.org  |  [LANGAGES]  |  Perl, Python, Rebol, shell, etc. (Modérateurs: ptidom, tetram9)  |  Sujet: [résolu]-[Perl] lenteur avec XML::XPath 0 Membres et 3 Invités sur ce sujet.
Pages: [1] Imprimer
Auteur Sujet: [résolu]-[Perl] lenteur avec XML::XPath  (Lu 2181 fois)
tetram9
Moderator
Dieu
*****
Sexe: Homme
Messages: 1252


Voir le profil WWW
[résolu]-[Perl] lenteur avec XML::XPath
« le: 27 Juillet 2005, 17:38:52 »

salut,

J'ai un script qui utilise XML::XPath et je trouve ce script particulièrement lent !
Il ne réalise pourtant que 5 requêtes XPath sur un fichier XML qui ne pèse que 50 ko environ...

Est-ce qu'il serait de notoriété publique que XML::XPath soit un module lent ou bien ai-je codé avec les pieds ?
« Dernière édition: 04 Août 2005, 17:23:08 par tetram9 » Journalisée

trinitacs
Mangue.org - CA
Dieu
*****
Sexe: Homme
Messages: 519


Voir le profil
Re: [Perl] lenteur avec XML::XPath
« Répondre #1 le: 27 Juillet 2005, 19:19:34 »

Pour avoir codé un parseur xml il chargeait 60ko de xml en 0,009 sec. Donc on va dire que le temps du chargement du fichier ne devrait pas poser de problème. Ensuite toutes les requêtes XPath ne sont pas équivalentes en terme d'éxécution. Un /foo/bar sera plus rapide qu'un //foo/bar tout comme un /foo/bar[1] sera plus rapide qu'un /foo/bar. Donc essaye de paufiner tes requêtes XPath pour limiter le parcours dans l'arbre xml. Par expériences les requêtes XPath peuvent vraiment plomber les perfs. Par exemple l'opérateur | est désastreux niveau performances. Pour preuve il n'y a qu'à voir oo2mangue.xsl.

Montre nous ton doc xml et tes requêtes XPath on pourra t'aider à les améliorer ;-)
Journalisée

Tonight, I'm rock'n'roll star
tetram9
Moderator
Dieu
*****
Sexe: Homme
Messages: 1252


Voir le profil WWW
Re: [Perl] lenteur avec XML::XPath
« Répondre #2 le: 28 Juillet 2005, 00:34:11 »

Bon, je passe la seconde alors... Je vous explique ce que je fais, ensuite je vous donne le code que j'ai fait avec mes doigts de pieds Smiley

Il s'agit de parser un fichier XML issu d'une extension de Firefox : Bookmark synchroniser. Cette extension permet d'exporter les bookmarks de firefox sur un serveur distant et ce au format XBEL (XML Bookmark Exchange Language). il suffit ensuite d'avoir l'extension sur toutes les machines où vous avez une session et vos bookmarks sont toujours à jour.

Du coup, je dispose sur mon serveur du fichier xml en question. Li'dée est que lorsque je surfe depuis une machine qui ne m'appartient pas, je puisse accéder à mes bookmarks quand même. Pour ça il me suffit de parser le fichier XML et d'afficher ça en html.

J'ai donc fait ce script en Perl avec le module XML::XPath :

Code:
#!/usr/bin/perl -w

use XML::XPath;
use XML::XPath::XMLParser;
use strict;

my $prefix = "rdf\%3A\#\$";

print "Content-type: text/html\n\n";
my $FolderId = $ENV{'QUERY_STRING'};

if($FolderId eq "") {
  TraiteXBEL("");
}
else {
  TraiteXBEL($FolderId);
}

exit(0);

sub TraiteXBEL {
  # usage: TraiteXBEL($InputFolderId);
  #
  # * SI $FolderId est defini ALORS on liste les dossiers et les liens dans le dossier correspondant ;
  # * SI $FolderId est vide ALORS on liste les dossiers et les liens à la racine.

  my ($InputFolderId) = @_;

  my $XPATH_REQUEST1;
  my $XPATH_REQUEST2;
  my $XPATH_REQUEST3;
  my $XPATH_REQUEST4;
  my $XPATH_REQUEST5;

  my $XBEL = XML::XPath->new('./xbel.xml');

  if($InputFolderId eq "") {
    $XPATH_REQUEST1='/xbel/folder/@id';
  }
  else {
    $InputFolderId = $prefix.$InputFolderId;
    $XPATH_REQUEST1='//folder[@id=\''.$InputFolderId.'\']/folder/@id';
  }

  my $nodeset = $XBEL->find($XPATH_REQUEST1);

  my $NbFolders = $nodeset->size();
  print "<h2>Rubriques ($NbFolders)</h2>\n";

  foreach my $node ( $nodeset->get_nodelist ) {

      my $FolderId = XML::XPath::XMLParser::as_string( $node );
      $FolderId =~ s/[ ]+?id="(.*?)"/$1/g;

# On extrait le suffixe du $FolderId pour eviter les caracteres speciaux.
my $suffix = substr($FolderId,8);

      # liste des dossiers
      $XPATH_REQUEST2='//folder[@id=\''.$prefix.$suffix.'\']/title/text()';
      my $FolderName = $XBEL->find($XPATH_REQUEST2);

      print "<ul>";
      my $nom = XML::XPath::XMLParser::as_string( $FolderName->get_nodelist );
      print "<li><a href=\"./xbel.cgi?$suffix\">$nom</a></li>\n";
      print "</ul>";
  }

  # liste des liens
  if($InputFolderId eq "") {
    $XPATH_REQUEST3='/xbel/bookmark/@id';
  }
  else {
    $XPATH_REQUEST3='//folder[@id=\''.$InputFolderId.'\']/bookmark/@id';
  }

  $nodeset = $XBEL->find($XPATH_REQUEST3); # on r�up�e tous les attr: id

  my $NbLiens = $nodeset->size();
  print "<h2>Marque-pages ($NbLiens)</h2>\n";

  foreach my $node ( $nodeset->get_nodelist ) {

      my $BookmarkId = XML::XPath::XMLParser::as_string( $node );
      $BookmarkId =~ s/[ ]+?id="(.*?)"/$1/g;

      # liste des bookmarks

      $XPATH_REQUEST4='//bookmark[@id=\''.$BookmarkId.'\']/title/text()';
      my $BookmarkTitles = $XBEL->find($XPATH_REQUEST4);
      my $BookmarkTitle = XML::XPath::XMLParser::as_string( $BookmarkTitles->get_nodelist );

      $XPATH_REQUEST5='//bookmark[@id=\''.$BookmarkId.'\']/@href';
      my $BookmarkUrls = $XBEL->find($XPATH_REQUEST5);
      my $BookmarkUrl = XML::XPath::XMLParser::as_string( $BookmarkUrls->get_nodelist );
      $BookmarkUrl =~ s/[ ]+?href="(.*?)"/$1/g;

      print "<a href=\"$BookmarkUrl\">$BookmarkTitle</a><br />\n";
  }
}

il y a deux cas de figure :
  • le script reçoit un id en argument par l'url (méthode GET)
  • ou pas

Si aucun argument n'est passé par l'url, alors on affiche la liste des dossiers (balise folder) grâce à leur attribut id. ainsi que la liste des bookmarks à la racine. Si un id est passé en argument, alors, on fait la même démarche mais en partant du dossier correspondant.

Voila...
Journalisée

trinitacs
Mangue.org - CA
Dieu
*****
Sexe: Homme
Messages: 519


Voir le profil
Re: [Perl] lenteur avec XML::XPath
« Répondre #3 le: 28 Juillet 2005, 07:44:11 »

Le problème ce sont tes reqêtes qui commencent par //folder. À chaque fois ça force le moteur XPath à parcourir le document en entier. Tu fais 5 requêtes avec // dont certaines dans un foreach. Je pense que le plus simple serait de faire une fonction récursive qui descend d'un niveau dans les dossiers à chaque fois. Le script parcoura tjrs le document en entier mais une seule fois et non plus plein de fois comme c'est le cas.

Mais le mieux c'est une feuille xslt ;-)
Journalisée

Tonight, I'm rock'n'roll star
tetram9
Moderator
Dieu
*****
Sexe: Homme
Messages: 1252


Voir le profil WWW
Re: [Perl] lenteur avec XML::XPath
« Répondre #4 le: 28 Juillet 2005, 09:05:21 »

Le problème ce sont tes reqêtes qui commencent par //folder. À chaque fois ça force le moteur XPath à parcourir le document en entier. Tu fais 5 requêtes avec // dont certaines dans un foreach. Je pense que le plus simple serait de faire une fonction récursive qui descend d'un niveau dans les dossiers à chaque fois. Le script parcoura tjrs le document en entier mais une seule fois et non plus plein de fois comme c'est le cas.

Ca veut dire qu'il faudrait construire une requête différente à chaque appel de la fonction ?

Mais le mieux c'est une feuille xslt ;-)

Peut-être mais je connait pas XSLT, vu que ton cours sur le sujet n'est pas en ligne Cool
Journalisée

Lawouach
Mangue.org - CA
Dieu
*****
Sexe: Homme
Messages: 1303

meh


Voir le profil WWW
Re: [Perl] lenteur avec XML::XPath
« Répondre #5 le: 28 Juillet 2005, 12:03:38 »

Pourrais tu mettre en ligne ton doc xml stp ? Smiley
Journalisée
tetram9
Moderator
Dieu
*****
Sexe: Homme
Messages: 1252


Voir le profil WWW
Re: [Perl] lenteur avec XML::XPath
« Répondre #6 le: 28 Juillet 2005, 13:44:11 »

Pourrais tu mettre en ligne ton doc xml stp ? Smiley

En voila un bout (parce qu'en entier, c'est trop long...)
mais ce morceau suffit pour avoir une idée précise de la structure du document

Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xbel PUBLIC "+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML" "http://pyxml.sourceforge.net/topics/dtds/xbel-1.0.dtd">
<xbel>
  <title>Marque-pages</title>
  <info>
    <metadata owner="Mozilla" BookmarksToolbarFolder="rdf:#$lBpT9"/>
  </info>
 
  <folder id="rdf%3A#$bHpT9">
    <title>Mangue.org</title>
   
    <bookmark id="rdf%3A#$MIpT9" href="http://www.mangue.org/">
      <title>Asso - Mangue.org</title>
    </bookmark>
    <bookmark id="rdf%3A#$NIpT9" href="http://communaute.mangue.org/">
      <title>Communauté Mangue.Org</title>
    </bookmark>
    <bookmark id="rdf%3A#$PIpT9" href="http://forum.mangue.org/">
      <title>Forum Mangue.org</title>
    </bookmark>
  </folder>
 
  <folder id="rdf%3A#$bCpT9">
    <title>Livres</title>
   
    <folder id="rdf%3A#$AEpT9">
      <title>O'Reilly</title>
      <bookmark id="rdf%3A#$KHpT9" href="http://learninglab.oreilly.com/">
        <title>O'Reilly Learning Lab</title>
      </bookmark>
      <bookmark id="rdf%3A#$LHpT9" href="http://www.oreilly.com/">
        <title>O'Reilly.com</title>
      </bookmark>
      <bookmark id="rdf%3A#$MHpT9" href="http://www.oreilly.fr/">
        <title>O'Reilly - Site français</title>
      </bookmark>
      <bookmark id="rdf%3A#$NHpT9" href="http://www.oreilly.com/openbook/">
        <title>O'Reilly Open Books Project</title>
      </bookmark>
      <bookmark id="rdf%3A#$OHpT9" href="http://www.oreillynet.com/">
        <title>O'Reilly Network</title>
      </bookmark>
      <bookmark id="rdf%3A#$PHpT9" href="http://conferences.oreillynet.com/">
        <title>O'Reilly Conferences</title>
      </bookmark>
      <bookmark id="rdf%3A#$QHpT9" href="http://www.onlamp.com/">
        <title>O'Reilly - ONLamp.com</title>
      </bookmark>
      <bookmark id="rdf%3A#$RHpT9" href="http://www.onjava.com/">
        <title>O'Reilly - ONJava.com</title>
      </bookmark>
      <bookmark id="rdf%3A#$SHpT9" href="http://www.perl.com/">
        <title>O'Reilly - Perl.com</title>
      </bookmark>
      <bookmark id="rdf%3A#$THpT9" href="http://www.xml.com/">
        <title>O'Reilly - XML.com</title>
      </bookmark>
      <bookmark id="rdf%3A#$UHpT9" href="http://www.windowsdevcenter.com/">
        <title>O'Reilly - WindowsDevCenter.com</title>
      </bookmark>
    </folder>
 
    <bookmark id="rdf%3A#$BEpT9" href="http://www.freeprogrammingresources.com/books.html">
      <title>Free Programming Books, freeprogrammingresources.com</title>
    </bookmark>
    <bookmark id="rdf%3A#$CEpT9" href="http://www.freetechbooks.com">
      <title>FreeTechBooks</title>
    </bookmark>
    <bookmark id="rdf%3A#$DEpT9" href="http://www.maththinking.com/boat/booksIndex.html">
      <title>Ju Rao's Homepage: Computer Books</title>
    </bookmark>
    <bookmark id="rdf%3A#$EEpT9" href="http://bookshelf.sleepnet.net/files/">
      <title>Livres d'informatique</title>
    </bookmark>
    <bookmark id="rdf%3A#$FEpT9" href="http://www.numerical-recipes.com/">
      <title>Numerical Recipes Home Page</title>
    </bookmark>
    <bookmark id="rdf%3A#$GEpT9" href="http://www.geocities.com/xiaolinli/FreeEBooksProg.htm">
      <title>Programming Books</title>
    </bookmark>
  </folder>
 
</xbel>
Journalisée

Lawouach
Mangue.org - CA
Dieu
*****
Sexe: Homme
Messages: 1303

meh


Voir le profil WWW
Re: [Perl] lenteur avec XML::XPath
« Répondre #7 le: 28 Juillet 2005, 13:52:18 »

Hmm effectivement une feuille de style de type push serait l'ideal ici...

Je regarde ça
Journalisée
tetram9
Moderator
Dieu
*****
Sexe: Homme
Messages: 1252


Voir le profil WWW
Re: [Perl] lenteur avec XML::XPath
« Répondre #8 le: 28 Juillet 2005, 13:59:30 »

Hmm effectivement une feuille de style de type push serait l'ideal ici...

C'est quoi ?
Journalisée

Lawouach
Mangue.org - CA
Dieu
*****
Sexe: Homme
Messages: 1303

meh


Voir le profil WWW
Re: [Perl] lenteur avec XML::XPath
« Répondre #9 le: 28 Juillet 2005, 14:03:53 »

Voilà un exemple de feuille XSLT type PUSH:

Code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="html" indent="yes" encoding="UTF-8" omit-xml-declaration="yes"/>
    <xsl:template match="/xbel">
        <xsl:apply-templates select="//folder" />
    </xsl:template>
   
    <xsl:template match="folder">
        <ul>
            <xsl:apply-templates select="bookmark" />
        </ul>
    </xsl:template>
   
    <xsl:template match="bookmark">
        <li>
            <xsl:apply-templates select="title" />
        </li>
    </xsl:template>
   
    <xsl:template match="title">
            <xsl:apply-templates />
    </xsl:template>
</xsl:stylesheet>

Type PULL :
Code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="html" indent="yes" encoding="UTF-8" omit-xml-declaration="yes"/>
    <xsl:template match="/xbel">
        <xsl:for-each select="//folder">
            <ul>
                  <xsl:for-each select="bookmark">
                      <li><xsl:value-of select="title"/></li>
                  </xsl:for-each>
            </ul>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

Sur l'exemple d'XML que tu donnes ça retourne ça dans les deux cas:

Code:
<ul>
   <li>Asso - Mangue.org</li>
   <li>Communaut&eacute; Mangue.Org</li>
   <li>Forum Mangue.org</li>
</ul>
<ul>
   <li>Free Programming Books, freeprogrammingresources.com</li>
   <li>FreeTechBooks</li>
   <li>Ju Rao's Homepage: Computer Books</li>
   <li>Livres d'informatique</li>
   <li>Numerical Recipes Home Page</li>
   <li>Programming Books</li>
</ul>
<ul>
   <li>O'Reilly Learning Lab</li>
   <li>O'Reilly.com</li>
   <li>O'Reilly - Site fran&ccedil;ais</li>
   <li>O'Reilly Open Books Project</li>
   <li>O'Reilly Network</li>
   <li>O'Reilly Conferences</li>
   <li>O'Reilly - ONLamp.com</li>
   <li>O'Reilly - ONJava.com</li>
   <li>O'Reilly - Perl.com</li>
   <li>O'Reilly - XML.com</li>
   <li>O'Reilly - WindowsDevCenter.com</li>
</ul>

PULL : C'est le createur de la feuille de style qui tire du document XML uniquement les éléments dont il a besoin (la boucle xsl:for-each et le xsl:value)
PUSH: La feuille de style indique simplement comment traiter les éléments quand ils sont rencontrés dans le document XML. C'est le processeur XSLT qui lorsqu'il rencontre un noeud XML regarde dans la feuille de style : "est ce que j'ai un template pour la transformation de ce noeud? si oui je l'utilise, sinon je ne fais rien!"

Le modèle PUSH est légèrement plus compliqué et plus verbeux mais plus modulaire aussi et plus indépendant de la structure même du document XML.

La différence n'est peut etre pas flagrante ici car dans les deux cas je fais un "//folder" qui récupère dès le debut tous les noeuds folder.
« Dernière édition: 28 Juillet 2005, 14:27:50 par Lawouach » Journalisée
trinitacs
Mangue.org - CA
Dieu
*****
Sexe: Homme
Messages: 519


Voir le profil
Re: [Perl] lenteur avec XML::XPath
« Répondre #10 le: 28 Juillet 2005, 20:55:17 »

Citation
Citation
Le problème ce sont tes reqêtes qui commencent par //folder. À chaque fois ça force le moteur XPath à parcourir le document en entier. Tu fais 5 requêtes avec // dont certaines dans un foreach. Je pense que le plus simple serait de faire une fonction récursive qui descend d'un niveau dans les dossiers à chaque fois. Le script parcoura tjrs le document en entier mais une seule fois et non plus plein de fois comme c'est le cas.

Ca veut dire qu'il faudrait construire une requête différente à chaque appel de la fonction ?

Qqch qui ressemblerait à ça. Il suffit juste de donner le noeud racine à la fonctione et le tour est joué. Vive les cgi en Perl ;-)
Code:
sub display_bookmarks( $parent )
{
    $children = $parent->find( "folder" );
    foreach my $child ( $children->get_nodelist() )
        display_bookmarks( $child );

    $children = $parent->find( "bookmark" );
    foreach my $child ( children->get_nodelist() )
        print $child->get_attribute( "href" );
}

Citation
Peut-être mais je connait pas XSLT, vu que ton cours sur le sujet n'est pas en ligne Cool
Pinaise je l'avais oublié Sad Ce we je m'en occupe juste avant de prendre le train :-)
Journalisée

Tonight, I'm rock'n'roll star
Lawouach
Mangue.org - CA
Dieu
*****
Sexe: Homme
Messages: 1303

meh


Voir le profil WWW
Re: [Perl] lenteur avec XML::XPath
« Répondre #11 le: 02 Août 2005, 09:39:07 »

Journalisée
tetram9
Moderator
Dieu
*****
Sexe: Homme
Messages: 1252


Voir le profil WWW
Re: [Perl] lenteur avec XML::XPath
« Répondre #12 le: 02 Août 2005, 17:18:36 »

j'ai écrit un billet sur mon blog pour décrire ce que j'ai fait avec ce script. Le résultat est visible : ici.
Journalisée

madflo
Mangue.org - CA
Sr. Member
*****
Sexe: Homme
Messages: 261


I eat users


Voir le profil WWW
Re: [Perl] lenteur avec XML::XPath
« Répondre #13 le: 02 Août 2005, 21:49:39 »

salut,

J'ai un script qui utilise XML::XPath et je trouve ce script particulièrement lent !
Il ne réalise pourtant que 5 requêtes XPath sur un fichier XML qui ne pèse que 50 ko environ...

Est-ce qu'il serait de notoriété publique que XML::XPath soit un module lent ou bien ai-je codé avec les pieds ?

Si, c'est extrèmement lent. Quand je l'utilise pour du SOAP avec les webservices Amazon, c'est assez impressionnant de lenteur et ultra gourmand en cpu. Genre 1s sur un PIII 600 pour extraire une info d'un sous node (genre node1/node2/node3) sur un fichier de... quelques ko.
Journalisée
Lawouach
Mangue.org - CA
Dieu
*****
Sexe: Homme
Messages: 1303

meh


Voir le profil WWW
Re: [résolu]-[Perl] lenteur avec XML::XPath
« Répondre #14 le: 13 Août 2005, 22:46:06 »

eh eh un exemple en Python avec amara :

http://uche.ogbuji.net/uche.ogbuji.net/tech/4suite/amara/manual (cherchez xbel)

amara est un package python qui transforme un doc xml en de simples objets python... tres pratique Smiley
Journalisée
Pages: [1] Imprimer 
forum.mangue.org  |  [LANGAGES]  |  Perl, Python, Rebol, shell, etc. (Modérateurs: ptidom, tetram9)  |  Sujet: [résolu]-[Perl] lenteur avec XML::XPath
Aller à:  

forum.mangue.org | Propulsé par SMF 1.0.8.
© 2001-2004, Lewis Media. Tous droits réservés.
Page générée en 0.218 secondes avec 18 requêtes.