IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

XSL/XSLT/XPATH XML Discussion :

performances en cascade


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Membre habitué
    Homme Profil pro
    Architecte senior Java EE/Spring - ScrumMaster
    Inscrit en
    Juin 2010
    Messages
    229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France

    Informations professionnelles :
    Activité : Architecte senior Java EE/Spring - ScrumMaster
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 229
    Points : 162
    Points
    162
    Par défaut performances en cascade
    (re)Bonjour,

    J'ai de gros pbs de performances sur un script (dans une série de 5 qui s'enchaînent sur un même flux). Je ne comprends pas très bien pourquoi ça rame alors que le script précédent est bien plus complexe...

    Je me suis aperçu, par exemple, que mes feuilles de style étaient en indent="true" ; je suis passé d'un fichier intermédiaire de 40Mo à 12.5Mo en le passant à "false", mais les performances ne se sont pas améliorées (elles se sont même un peu dégradées, pour tout dire).

    Voici le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
     
    <xsl:template match="node()">
    	<xsl:param name="parentRef" select="0" />
    	<xsl:variable name="pos"><xsl:number level="any" count="*[local-name()!='val' and not(@ref) and not(@reference)]" /></xsl:variable>
     
    	<xsl:copy>
    		<!-- l'attribut @class doit apparaître en première position -->
    		<xsl:copy-of select="@class" />
    		<!-- ajout d'un attribut @id séquenciel -->
    		<xsl:if test="local-name()!='val' and not(@ref) and not(@reference)">
    			<xsl:attribute name="id"><xsl:value-of select="$pos - 1" /></xsl:attribute>
    		</xsl:if>
    		<!-- l'attribut @parent sera remplacé par un noeud ci-dessous -->
    		<xsl:copy-of select="@*[local-name()!='class' and local-name()!='parent']" />
     
     
    		<xsl:if test="local-name()='md'">
    			<xsl:element name="po">
    				<xsl:attribute name="class">p</xsl:attribute>
    				<xsl:attribute name="ref"><xsl:value-of select="$parentRef" /></xsl:attribute>
    			</xsl:element>
    		</xsl:if>
     
    		<!-- un certain ordre doit être respecté pour les balises -->
    		<xsl:apply-templates select="vi|dc|md|t">
    			<xsl:with-param name="parentRef"><xsl:value-of select="$pos - 1" /></xsl:with-param>
    		</xsl:apply-templates>
     
    		<xsl:if test="@parent">
    			<xsl:element name="pa">
    				<xsl:attribute name="ref"><xsl:value-of select="$parentRef" /></xsl:attribute>
    			</xsl:element>
    		</xsl:if>
     
    		<xsl:apply-templates select="*[local-name()!='vi' and local-name()!='dc' and local-name()!='md' and local-name()!='t']">
    			<xsl:with-param name="parentRef"><xsl:value-of select="$pos - 1" /></xsl:with-param>
    		</xsl:apply-templates>
    	</xsl:copy>
     
    	<xsl:if test="local-name()='vp'">
    		<xsl:element name="vc">
    			<xsl:attribute name="class">V</xsl:attribute>
    			<xsl:attribute name="ref"><xsl:value-of select="$pos - 1" /></xsl:attribute>
    		</xsl:element>
    	</xsl:if>
    </xsl:template>
    Est-ce que quelqu'un voit des choses qui pourraient être améliorées au niveau des expressions xPath ? Dois-je remplacer mes tests par des sous-templates ??
    Merci d'avance pour vos remarques.

  2. #2
    Membre habitué
    Homme Profil pro
    Architecte senior Java EE/Spring - ScrumMaster
    Inscrit en
    Juin 2010
    Messages
    229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France

    Informations professionnelles :
    Activité : Architecte senior Java EE/Spring - ScrumMaster
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 229
    Points : 162
    Points
    162
    Par défaut
    Bonsoir,

    Quelqu'un sait-il, SVP, si :
    1. il est plus performant d'écrire les balises simples avec des balises xsl:element et xsl:attribute, ou directement avec <y xx="{...}" />
    2. il est plus performant de faire un test de balise avec local-name()='X", ou self::X ?


    Merci d'avance.

  3. #3
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 563
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 563
    Points : 21 627
    Points
    21 627
    Par défaut
    En principe, aucune de ces deux questions n'est question de performance. Ce n'est qu'une question de commodité et de réduction de risques de bugs.

    Après, pour chacun de ces points, tout dépend de l'implémentation du moteur XSLT/XPath. Je n'ai rien remarqué de ce genre avec Xalan ni Saxon.

  4. #4
    Membre habitué
    Homme Profil pro
    Architecte senior Java EE/Spring - ScrumMaster
    Inscrit en
    Juin 2010
    Messages
    229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France

    Informations professionnelles :
    Activité : Architecte senior Java EE/Spring - ScrumMaster
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 229
    Points : 162
    Points
    162
    Par défaut
    OK ; j'avais cru détecter une baisse de perf en passant à une écriture plus "ramassée" ; je m'étais dit que c'était parce qu'on passait par xPath...
    REM : j'utilise saxon9he.
    Je vais virer pas-à-pas chaque rubrique pour voir où ça tourne en rond.

    Ce qui est vexant, c'est qu'au moins 2 autres de mes scripts (sur 5) ressemblent beaucoup à celui-ci et qu'ils ne font pas tant de chichis...

  5. #5
    Membre habitué
    Homme Profil pro
    Architecte senior Java EE/Spring - ScrumMaster
    Inscrit en
    Juin 2010
    Messages
    229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France

    Informations professionnelles :
    Activité : Architecte senior Java EE/Spring - ScrumMaster
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 229
    Points : 162
    Points
    162
    Par défaut
    OK, le pb vient de l'application du template avec les négations dans le select.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:apply-templates select="*[local-name()!='vi' and local-name()!='dc' and local-name()!='md' and local-name()!='t']">
    Je préfèrerais continuer à fonctionner par négation ; le nb de cas peut être assez conséquent... Est-ce que quelqu'un connaitrait, par hasard, une autre façon d'écrire cette expression ? Ou un moyen d'insérer une balise (issue d'un attribut, cf. plus haut) au milieu d'autres en tenant compte de l'ordre ??
    Merci d'avance.

  6. #6
    Expert confirmé
    Avatar de Loceka
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    2 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 2 276
    Points : 4 843
    Points
    4 843
    Par défaut
    Tu peux essayer de passer par la négation du test opposé (je ne sais pas si c'est meilleur côté perf, j'en doute même) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    not(local-name()='vi' or local-name()='dc' or local-name()='md' or local-name()='t')
    Une autre possibilité, moins lisible mais peut-être plus optimale (là encore j'ai un gros doute) serait de concaténer dans un string les éléments dont tu ne veux pas et de tester l'égalité avec un contains :
    Code X : Sélectionner tout - Visualiser dans une fenêtre à part
    not(contains('vi<dc<md<t',local-name()))
    Le séparateur '<' étant certain de ne pas se trouver dans un nom de balise.

  7. #7
    Membre habitué
    Homme Profil pro
    Architecte senior Java EE/Spring - ScrumMaster
    Inscrit en
    Juin 2010
    Messages
    229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France

    Informations professionnelles :
    Activité : Architecte senior Java EE/Spring - ScrumMaster
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 229
    Points : 162
    Points
    162
    Par défaut
    Merci pour les tuyaux ; ça ouvre des horizons !

    Entretemps, je me suis lancé sur une autre piste : ma balise doit être inséré AVANT une certaine balise <po>, disons. Du coup, je tente d'utiliser preceding-sibling ; mais là encore je dois dire que XSLT se révèle anti-intuitif...

    Si j'ai bien compris, les nœuds que l'on récupère sont dans l'ordre inverse du document... je dois dire que c'est la classe ! Je sais bien que mes déboires ne sont imputables qu'à mon inexpérience en la matière mais... sérieusement : en sens inverse du document ! QUI a besoin de ça par défaut ??? Bref.

    Du coup, j'en ai profité pour découper mon template. Si j'ai bien compris (?), je peux avoir un template "*" ou "node()" (quelle différence ?) et d'autres templates, le plus précis étant pris en compte avant les autres :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    <xsl:template match="*">
    ...
    <xsl:template match="fi">
    ...
    <xsl:template match="fi[@parent]">
    	<xsl:param name="parentRef" select="0" />
    ... gestion de mon fameux attribut "parent"
    <!-- un certain ordre DEVRAIT être respecté pour les balises -->
    <xsl:apply-templates select="preceding-sibling::po" />
     
    <pa ref="{$parentRef}" />
     
    <xsl:apply-templates select="po" />
    Je passe de 90s à 17s (9s si je retire complètement le "select not" qui suivent l'injection dans l'exemple de départ). MAIS l'arbre résultat n'est plus bon... je dois avoir besoin d'explications sur l'axe "preceding", non ?
    J'ai le pressentiment que je dois en fait récupérer les frères du nœud courant qui s'appellent "po" ; c'est-à-dire rien du tout... qq'un, SVP ??

  8. #8
    Expert confirmé
    Avatar de Loceka
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    2 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 2 276
    Points : 4 843
    Points
    4 843
    Par défaut
    Citation Envoyé par tooms4444 Voir le message
    Si j'ai bien compris, les nœuds que l'on récupère sont dans l'ordre inverse du document...
    Je suis pas sûr de bien comprendre ce que tu dis. Si tu dis que le parseur XSL lit le document XML en partant de la fin, là je sais pas (mais ça doit dépendre de comment le parseur en question est codé). Si tu dis que, en faisait un preceding-sibling sur l'élément t2, on obtient t3 dans <t><t1/><t2/><t3/></t> c'est faux.

    Citation Envoyé par tooms4444 Voir le message
    je peux avoir un template "*" ou "node()" (quelle différence ?)
    La différence c'est que node() match à la fois les éléments (balises) et les attributs tandis que "*" ne match que les éléments, les attributs étant matchés par "@*".

    Citation Envoyé par tooms4444 Voir le message
    je dois avoir besoin d'explications sur l'axe "preceding"
    en effet ^_^ preceding-sibling, de même que tous les axes et d'ailleurs tout chemin XPath relatif, s'applique relativement à l'élément courant (c'est une des notions les plus importantes en XSL : toujours savoir quel est l'élément courant).
    Ainsi <xsl:apply-templates select="preceding-sibling::po" /> retournera tous les éléments "po" qui sont frères de l'élément courant mais avant lui dans l'arborescence. Ce n'est pas du tout ce que tu souhaites.

    Toi tu souhaites tous les frères précédents l'élément "po" soit : <xsl:apply-templates select="po/preceding-sibling::*" />. Dans le cas où "po" est un fils de l'élément courant, bien entendu.

  9. #9
    Membre habitué
    Homme Profil pro
    Architecte senior Java EE/Spring - ScrumMaster
    Inscrit en
    Juin 2010
    Messages
    229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France

    Informations professionnelles :
    Activité : Architecte senior Java EE/Spring - ScrumMaster
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 229
    Points : 162
    Points
    162
    Par défaut
    Citation Envoyé par Loceka Voir le message
    Je suis pas sûr de bien comprendre ce que tu dis. Si tu dis que le parseur XSL lit le document XML en partant de la fin, là je sais pas (mais ça doit dépendre de comment le parseur en question est codé). Si tu dis que, en faisait un preceding-sibling sur l'élément t2, on obtient t3 dans <t><t1/><t2/><t3/></t> c'est faux.
    Nope ; ce que j'ai compris (hum), c'est que preceding-sibling::Child[1], par exemple, renvoie le nœud juste avant le nœud courant (à contresens donc du sens de lecture du document), tandis que following-sibling::Child[1] renvoie le nœud juste après le nœud courant (dans le sens de lecture du document, donc).
    On peut chercher longtemps AMHA, en écrivant intuitivement preceding-sibling::Child[last()], sans comprendre ce qui cloche...

  10. #10
    Membre habitué
    Homme Profil pro
    Architecte senior Java EE/Spring - ScrumMaster
    Inscrit en
    Juin 2010
    Messages
    229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France

    Informations professionnelles :
    Activité : Architecte senior Java EE/Spring - ScrumMaster
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 229
    Points : 162
    Points
    162
    Par défaut
    La différence c'est que node() match à la fois les éléments (balises) et les attributs tandis que "*" ne match que les éléments, les attributs étant matchés par "@*".
    Donc, "node" qui veut dire "noeud" signifie "les noeuds et les attributs"... hum. Je crois que je vais craquer merci pour l'explication, en tout cas.

  11. #11
    Expert confirmé
    Avatar de Loceka
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    2 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 2 276
    Points : 4 843
    Points
    4 843
    Par défaut
    Ah

    J'ai jamais trop utilisé les preceding-sibling mais j'aurais aussi écrit last() pour avoir le... dernier (donc celui juste avant l'élément courant).

    Si ce que tu dis est vrai c'est effectivement anti-intuitif. D'ailleurs je viens de tester et en effet c'est tout à fait ça : le [1] correspond au dernier. Etrange...

  12. #12
    Membre habitué
    Homme Profil pro
    Architecte senior Java EE/Spring - ScrumMaster
    Inscrit en
    Juin 2010
    Messages
    229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France

    Informations professionnelles :
    Activité : Architecte senior Java EE/Spring - ScrumMaster
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 229
    Points : 162
    Points
    162
    Par défaut
    Toi tu souhaites tous les frères précédents l'élément "po" soit : <xsl:apply-templates select="po/preceding-sibling::*" />. Dans le cas où "po" est un fils de l'élément courant, bien entendu.
    Ah, oui ! TOUT A FAIT !!!! Merci, Merci, Merci !

    Du coup, j'ai écris ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    <xsl:apply-templates select="po/preceding-sibling::*">
    	<xsl:with-param name="parentRef"><xsl:value-of select="$pos - 1" /></xsl:with-param>
    </xsl:apply-templates>
     
    <pa ref="{$parentRef}" />
     
    <xsl:apply-templates select="po" />
    <xsl:apply-templates select="po/following-sibling::*" />
    Retour à... 82s
    Mais comment ça peut ramer autant ?!

  13. #13
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 563
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 563
    Points : 21 627
    Points
    21 627
    Par défaut
    Citation Envoyé par tooms4444 Voir le message
    Donc, "node" qui veut dire "noeud" signifie "les noeuds et les attributs"
    Nan, Loceka s'est trompé.

    - node() signifie "les éléments, les nœuds texte, et les processing-instructions" (ainsi que les commentaires si le moteur n'est pas censé les ignorer.)
    - * signifie en effet "les éléments"
    - @* signifie en effet "les attributs"
    - text() signifie "rien que les nœuds texte"

    Si on veut "les éléments et les attributs," il faut faire *|@*

  14. #14
    Membre habitué
    Homme Profil pro
    Architecte senior Java EE/Spring - ScrumMaster
    Inscrit en
    Juin 2010
    Messages
    229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France

    Informations professionnelles :
    Activité : Architecte senior Java EE/Spring - ScrumMaster
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 229
    Points : 162
    Points
    162
    Par défaut
    Merci, thelvin, tj
    J'en ai profité pour réviser en ligne ; pour ceux que ça intéresse : http://xml.chez.com/xslt/index.htm#noeud

    Curiosité intellectuelle (mais sait-on jamais, je pourrais gratter 2s) : par quoi remplacer mon appel au template "po"+"following-siblings" pour ne faire qu'un appel "inclusif" ?

  15. #15
    Membre habitué
    Homme Profil pro
    Architecte senior Java EE/Spring - ScrumMaster
    Inscrit en
    Juin 2010
    Messages
    229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France

    Informations professionnelles :
    Activité : Architecte senior Java EE/Spring - ScrumMaster
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 229
    Points : 162
    Points
    162
    Par défaut Good news
    Je viens de diviser le temps de traitement par 5 , en séparant les cas "hors jeu" (pas d'id à mettre en place) dans un template à part :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    	<!-- l'attribut @class doit apparaître en première position -->
    	<xsl:copy-of select="@class" />
    	<!-- ajout d'un attribut @id séquenciel -->
    	<xsl:attribute name="id"><xsl:value-of select="$pos - 1" /></xsl:attribute>
    	<xsl:copy-of select="@*[local-name()!='class']" />
    ...
    <xsl:template match="val|*[@ref or @reference]">
    	<xsl:copy>
    		<xsl:copy-of select="@*" />
    	</xsl:copy>
    </xsl:template>
    C'est vrai qu'il y en a pas mal ; du coup on économise tous les tests pour les "vraies" balises (poilues). REM : j'ai encore gagné 1s en mettant ce dernier template en tête de liste (???).
    Sur les plus gros fichiers, on passe de 3h à 25mn ; soit un facteur 12. Ce qui est encourageant, c'est que du coup la courbe de vitesse se détache de celle du volume d'entrée. Je me fixe l'objectif d'un plafond à 5mn, soyons fous !

    Tous ça, c'est grâce à vous car le forum m'a permis de prendre du recul sur le langage. Alors MERCI !

  16. #16
    Membre habitué
    Homme Profil pro
    Architecte senior Java EE/Spring - ScrumMaster
    Inscrit en
    Juin 2010
    Messages
    229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France

    Informations professionnelles :
    Activité : Architecte senior Java EE/Spring - ScrumMaster
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 229
    Points : 162
    Points
    162
    Par défaut et les "custom functions" ??
    Quelqu'un pourrait-il me dire si j'ai quoi que ce soit à espérer en termes de performances en convertissant mes "named templates" en "custom functions", SVP ?

    Dans le même ordre (?) d'idées, quel gain puis-je espérer avec une feuille de style compilée ?

    Merci d'avance.

Discussions similaires

  1. Problème de performance sur un calcul en cascade
    Par mars13008 dans le forum SQL
    Réponses: 11
    Dernier message: 19/04/2011, 11h38
  2. [maintenance][performance] Que faire comme maintenance ?
    Par woodwai dans le forum PostgreSQL
    Réponses: 5
    Dernier message: 06/11/2003, 15h39
  3. [ POSTGRESQL ] Problème de performance
    Par Djouls64 dans le forum PostgreSQL
    Réponses: 6
    Dernier message: 26/05/2003, 16h18
  4. [JDBC][connexion persistante] performances avec JDBC
    Par nawac dans le forum Connexion aux bases de données
    Réponses: 6
    Dernier message: 06/05/2003, 10h37
  5. performance entre 3DS, ase, asc ...
    Par amaury pouly dans le forum OpenGL
    Réponses: 3
    Dernier message: 24/03/2003, 11h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo