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

Linq Discussion :

Optimisation chargement fichier xml


Sujet :

Linq

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2007
    Messages : 31
    Points : 28
    Points
    28
    Par défaut Optimisation chargement fichier xml
    Bonjour a tous,

    Voila mon problème, je suis entrain de développer une application pour Windows Mobile qui va utiliser un fichier xml comme BDD.
    Forcement, j'utilise Linq to Xml pour manipuler mes données. Seulement voila, mon fichier fait plus de 140000 lignes et son chargement ainsi que les requetes sont excessivement longues... Beaucoup trop pour offrir une expérience utilisateur convenable.
    Ma requete n'est pas trop complexe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    var query = from c in xml.Descendants("client")
                            where c.Attribute("nom").Value.StartsWith("A") &&
                            c.Attribute("prenom").Value.StartsWith("A") &&
                            (string)c.Attribute("genre") == "H"
                            select new Personn
                            {
                                nom= (string)c.Element("nom"),
                                prenom= (string)c.Attribute("prenom"),
                             };
    Est ce qu'il existe une solution afin d'optimiser le temps pour executer la requete ?

    merci d'avance pour vos réponse.

    Guillaume

  2. #2
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2007
    Messages : 31
    Points : 28
    Points
    28
    Par défaut
    Personne n'a une petite piste ?
    j'ai essayé ceci pour charger le fichier en memoire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    while (buff != null)
                {
                    buff = sr.ReadLine();
                    if (buff == null) { break; }
                    else { 
                        nbLigne++;
                        this.programmeXML += buff + '\n';
                    }
                }
    Pour compter les lignes, sans la commande
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this.programmeXML += buff + '\n';
    la boucle s'execute en 15sec. Des que je rajoute
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this.programmeXML += buff + '\n';
    , c'est terminé... la boucle prend plus de 10minutes.

    Il s'agit ici d'un fichier de plus de 140000 lignes pour une taille de 1.1Mo...

    Une petite idée ?

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par djspank Voir le message
    Des que je rajoute this.programmeXML += buff + '\n';, c'est terminé... la boucle prend plus de 10minutes.
    Ben oui, tu crées 2 * 140000 instances de String, un peu plus longue à chaque fois... (2 fois parce que buff + '\n' crée aussi une nouvelle instance). Construire une chaine par concaténation est acceptable à petite échelle, mais dès que le nombre de chaines augmente c'est catastrophique pour les perfs... Il vaut mieux utiliser un StringBuilder, qui sert à ça.

    Mais de toutes façons, pour charger un fichier texte dans une String, il y a plus simple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this.programmeXML = File.ReadAllText(cheminDuFichier);
    Enfin de toutes façons je ne pense pas que ça changera grand chose : XDocument charge de toutes façons le document en mémoire, pas la peine de le faire explicitement...

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 073
    Points : 12 119
    Points
    12 119
    Par défaut
    1.1Mo, c'est un petit fichier.
    XDocument devrait largement faire l'affaire.
    Si cela devient plus grand, il faut se tourner vers les API de type SAX et c'est beaucoup moins conviviale que les XPath de XDocument et encore moins que Linq.

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Sinon, il y a peut-être moyen d'améliorer un peu ta requête : l'utilisation de Descendants("client") recherche des éléments <client> à tous les niveaux du document, alors que je suppose qu'ils sont tous au même niveau... donc il vaudrait mieux utiliser directement Elements("client") au niveau voulu pour éviter de chercher inutilement à tous les niveaux.

    Par exemple, en supposant que les éléments <client> soient directement sous l'élément racine :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    var query = from c in xml.Root.Elements("client")
                            where c.Attribute("nom").Value.StartsWith("A") &&
                            c.Attribute("prenom").Value.StartsWith("A") &&
                            (string)c.Attribute("genre") == "H"
                            select new Personn
                            {
                                nom= (string)c.Element("nom"),
                                prenom= (string)c.Attribute("prenom"),
                             };
    D'autre part, comment utilises-tu le résultat de cette requête ? Parce que ce n'est pas cette instruction elle-même qui prend du temps, vu que l'exécution des requêtes Linq est différée jusqu'au moment où tu l'énumères...

  6. #6
    Inactif
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    59
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : Algérie

    Informations forums :
    Inscription : Juillet 2009
    Messages : 59
    Points : 73
    Points
    73
    Par défaut Peut être
    Bonjour!
    faute de temps je peux pas le tester mais ... n'est ce pas vrai que le linq To DataSet est plus rapide (en terme de performances) que le linq To Xml? Pourquoi ne pas essayer de charger me fichier xml dans un dataset pour ensuite utiliser les filtres sur les DataTables (RowFilter). de cette façon tu évitera de faire des requetes sur un ensemble trop grand d'enregistrements.

    si jamais vous decidez de tester tenez moi informé.
    merci. sinon quand je termine mon job je le teste.
    bon courage

  7. #7
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par buxus Voir le message
    n'est ce pas vrai que le linq To DataSet est plus rapide (en terme de performances) que le linq To Xml?
    Une telle comparaison n'a pas de sens, on ne peut comparer que ce qui est comparable... un DataSet n'est pas un fichier XML (même s'il peut être enregistré sous forme de fichier XML)

    Citation Envoyé par buxus Voir le message
    Pourquoi ne pas essayer de charger me fichier xml dans un dataset pour ensuite utiliser les filtres sur les DataTables (RowFilter).
    N'importe quel fichier XML ne peut pas être chargé dans un DataSet, il faut que le schema corresponde...

  8. #8
    Inactif
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    59
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : Algérie

    Informations forums :
    Inscription : Juillet 2009
    Messages : 59
    Points : 73
    Points
    73
    Par défaut Je sais!!
    Merci Tomlev de t'intéresser a ce que j'ai écrit.
    Une telle comparaison n'a pas de sens, on ne peut comparer que ce qui est comparable... un DataSet n'est pas un fichier XML (même s'il peut être enregistré sous forme de fichier XML)
    je te signale que j'ai pas comparé entre de l'XML qui est un format, et entre autres, dans ce cas est utilisé comme fichier de données et un DataSet qui est une structure en mémoire ... j'ai parlé de performances.
    je sais aussi qu'il faut qu'il corresponde au schéma (xsd). d'ailleurs il existe des méthodes de création et chargement de DataSets à partir de fichiers xml.
    j'ai proposé et c'est au concerné de disposer.
    Merci quand même.

  9. #9
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par buxus Voir le message
    je te signale que j'ai pas comparé entre de l'XML qui est un format, et entre autres, dans ce cas est utilisé comme fichier de données et un DataSet qui est une structure en mémoire ... j'ai parlé de performances.
    Oui mais un XDocument est aussi une structure en mémoire, vu que le document XML est chargé en mémoire. Il est possible qu'une requête sur un DataSet soit plus rapide dans certains cas (notamment si on recherche par rapport à une clé primaire), mais je ne pense pas que la différence soit flagrante... il faudrait tester pour en avoir le coeur net

  10. #10
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2007
    Messages : 31
    Points : 28
    Points
    28
    Par défaut
    Bonjour a tous,

    Tout d'abord merci pour vos réponses.

    1.1Mo, c'est un petit fichier.
    Je me suis trompé sur la taille du fichier. 1.1Mo correspond a la taille zipper. Une fois dezippé le fichier fait 7 Mo et contient plus de 140000 lignes...
    Est ce que linq est un choix cohérent pour travailler sur un fichier aussi grand ? Sachant que je vais utiliser le Compact Framework...

    D'autre part, comment utilises-tu le résultat de cette requête ? Parce que ce n'est pas cette instruction elle-même qui prend du temps, vu que l'exécution des requêtes Linq est différée jusqu'au moment où tu l'énumères...
    J'utilise le resultat de la requete avec la fonction Je ne sais pas si c'est cela qui peut poser probleme. Par contre je vais essayer ta méthode concernant l'optimisation de la requete en utilisant Element("clients") puisque effectivement il se trouve directement après la racine.

    Buxus,
    Merci pour ta proposition, je vais vérifier si la structure de mon fichier xml est compatible avec linq to dataset et je te dirais si cela fonctionne.

    Merci a tous pour votre aide, je vous tiens au courant des que j'ai pu tester toutes ces possibilités.

Discussions similaires

  1. [DOM] Chargement fichier xml
    Par dib258 dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 22/08/2007, 10h03
  2. [FLASH MX2004] Pb chargement fichier xml
    Par didier974 dans le forum Flash
    Réponses: 13
    Dernier message: 21/09/2006, 14h25
  3. Chargement fichier XML
    Par guy777 dans le forum Général JavaScript
    Réponses: 12
    Dernier message: 25/07/2006, 10h02
  4. [C#] Problème chargement fichier xml dans treeview
    Par LE NEINDRE dans le forum Windows Forms
    Réponses: 4
    Dernier message: 23/06/2006, 14h10
  5. [C#2.0]DatagridView + Chargement fichier XML
    Par chnew dans le forum Windows Forms
    Réponses: 2
    Dernier message: 10/04/2006, 12h35

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