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

Windows Presentation Foundation Discussion :

Conseils de performance pour manipulation de grosses chaines de caractères


Sujet :

Windows Presentation Foundation

  1. #1
    Membre du Club
    Inscrit en
    Mars 2009
    Messages
    104
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 104
    Points : 69
    Points
    69
    Par défaut Conseils de performance pour manipulation de grosses chaines de caractères
    Salut à tous,

    Je ne suis pas développeur, j'ai juste un peu pratiqué le vb .net à l'époque (ainsi que ses prédécesseurs) et je suis en train de découvrir WPF à l'occasion d'un petit projet perso. Ce projet consiste à faire des opérations assez nombreuses sur des textes assez long (entre 10 000 et 300 000 mots). J'ai commencé par faire une macro word qui remplissait un fichier excel, mais j'aimerai ajouter des fonctions, récupérer une jolie interface et faire un portage "optimisé" sous WPF.

    Pour vous donner une idée, voilà les types d'algo que j'écris:
    - Comptage du nombre de mots
    - Indexation de chaque mot unique, avec le nombre d’occurrences de chacun
    - Écarts min/max et moyens entre chaque mot identique (si plus de 6 occurrences)
    - Calcul des longueurs moyennes de phrases et écarts-types
    - Calcul des longueurs moyennes de paragraphes et écarts-types
    - pour chaque mot unique, requêtes en lecture sur BDD *.mdb pour voir si le mot est en base. Pas eu moyen d'utiliser une BDD accdb (access 2013) à cause d'un problème de driver ACE

    Vu la taille du texte manipulé (entre 10 000 et 300 000 mots), je veux utiliser la meilleure approche en termes de performances. Voilà donc les questions:

    - Je veux instancier une classe "parseur" et une classe "analyseur" dans deux threads séparés. J'ai vu que WPF fourni la possibilité de faire des tâches asynchrones dans le thread d'interface, mais vu la charge, je crois que le multi thread est une meilleure option. Est-ce que vous confirmez?

    - Dans chacun de mes objets "parseur" et "analyseur" je veux pouvoir récupérer l'avancement des traitements sur le thread d'interface. En WPF, je suis supposé utiliser un dispatcher? Vous avez des bons exemples (simples) à me conseiller pour récupérer un feedback venant d'un thread séparé? Est-ce qu'un background worker peut faire l'affaire?

    - Pour le comptage des mots et les tâches qui suivront, je ne sais pas quelle est la meilleur méthode, toujours au niveau des performances.

    Voilà les options que j'ai identifié pour l'acquisition du texte:
    > Partir d'un string.split et remplir un tableau de string
    > un dataset
    > Une structure
    > utiliser un regex
    > le composant stringbuilder peut-il servir dans ce cas là?

    Pour la manipulation du texte (comptage, position et écarts des mots)
    > Ecrire dans une table de ma base mdb après comptage (donc travailler directement à partir du string [] , dataset, structure ou regex selon la solution adoptée)
    > Ecrire dans une table de ma base mdb avant comptage (donc faire le travail sur la BDD, chaque mot ayant une ligne dans une table).
    > Travailler directement à partir du string [] , dataset, structure ou regex selon la solution adoptée sans utiliser de base de données.

    Pour la comparaison avec ma table de référence, faut-il que je compare via mon soft ou que je passe directement les requêtes à la base access? Je précise que après chaque Matching, je dois faire un update dans ma table si j'ai choisi d'ecrire mon texte dans une autre table de ma base

    Enfin, à terme, je souhaite utiliser un type de base de données léger (comprendre "qui se déploie facilement") mais qui a de bonnes performances. Est-ce que j'y gagnerais à utiliser SQLite3? Pour le format de base accdb, je galère à cause d'une erreur apparemment classique ("le fournisseur 'Microsoft.ACE.OLEDB.12.0' n'est pas inscrit sur l'ordi local"). J'ai eu beau placer la plateforme cible par 32bits only et instaler le moteur de BDD access x64, ça n'a rien résolu. Si quelqu'un peut aider au passage, il est bienvenu :-)

    Voilà, pas mal de questions. Je prends toutes vos suggestions, réponses partielles ou avis personnels.

    Par avance, merci!

  2. #2
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    Citation Envoyé par billybobbonnet Voir le message
    Je veux instancier une classe "parseur" et une classe "analyseur" dans deux threads séparés. J'ai vu que WPF fourni la possibilité de faire des tâches asynchrones dans le thread d'interface, mais vu la charge, je crois que le multi thread est une meilleure option. Est-ce que vous confirmez?
    Ce que tu appelles tâches asynchrones c'est sans doute les appels à Dispatcher.BeginInvoke et en effet tes traitements n'ont rien à y faire, le thread UI étant assez occupé avec le rendu.

    Citation Envoyé par billybobbonnet Voir le message
    Dans chacun de mes objets "parseur" et "analyseur" je veux pouvoir récupérer l'avancement des traitements sur le thread d'interface. En WPF, je suis supposé utiliser un dispatcher? Vous avez des bons exemples (simples) à me conseiller pour récupérer un feedback venant d'un thread séparé? Est-ce qu'un background worker peut faire l'affaire?
    Le BackgroundWorker est exactement conçu pour ce besoin : il capture automatiquement le contexte d'origine et permet de notifier de l'avancement de la tâche.

    Citation Envoyé par billybobbonnet Voir le message
    Pour le comptage des mots et les tâches qui suivront, je ne sais pas quelle est la meilleur méthode, toujours au niveau des performances.

    Voilà les options que j'ai identifié pour l'acquisition du texte:
    > Partir d'un string.split et remplir un tableau de string
    > un dataset
    > Une structure
    > utiliser un regex
    > le composant stringbuilder peut-il servir dans ce cas là?
    A priori aucun intérêt d'utiliser le StringBuilder qui n'est pertinent que pour des opérations intensives de génération de chaines de caractères.

    Citation Envoyé par billybobbonnet Voir le message
    Pour la manipulation du texte (comptage, position et écarts des mots)
    > Ecrire dans une table de ma base mdb après comptage (donc travailler directement à partir du string [] , dataset, structure ou regex selon la solution adoptée)
    > Ecrire dans une table de ma base mdb avant comptage (donc faire le travail sur la BDD, chaque mot ayant une ligne dans une table).
    > Travailler directement à partir du string [] , dataset, structure ou regex selon la solution adoptée sans utiliser de base de données.

    Pour la comparaison avec ma table de référence, faut-il que je compare via mon soft ou que je passe directement les requêtes à la base access? Je précise que après chaque Matching, je dois faire un update dans ma table si j'ai choisi d'ecrire mon texte dans une autre table de ma base
    La base est OK pour le stockage après coup mais étant donné la spécificité de tes traitements tu ne devrais pas pouvoir en déléguer à la couche BDD, et de toute façon tu n'y gagnerais sûrement rien puisque locale.
    Déléguer du travail à une BDD est vraiment pertinent quand celle-ci est hébergée sur une autre machine, et en fait on ne fait qu'exploiter la puissance de calcul de son hôte, et éventuellement des algos spécifiques de la base.

    Citation Envoyé par billybobbonnet Voir le message
    Enfin, à terme, je souhaite utiliser un type de base de données léger (comprendre "qui se déploie facilement") mais qui a de bonnes performances. Est-ce que j'y gagnerais à utiliser SQLite3? Pour le format de base accdb, je galère à cause d'une erreur apparemment classique ("le fournisseur 'Microsoft.ACE.OLEDB.12.0' n'est pas inscrit sur l'ordi local"). J'ai eu beau placer la plateforme cible par 32bits only et instaler le moteur de BDD access x64, ça n'a rien résolu. Si quelqu'un peut aider au passage, il est bienvenu :-)
    SQLite sans hésiter pour au moins 3 raisons :
    - la facilité de déploiement (SQLite auto-suffisant)
    - les fonctionnalités, notamment le support riche de SQL et de la concurrence (à voir si ça a de l'importance dans ton cas)
    - les performances (là aussi ça peut ne pas être un critère important)
    Formateur expert .Net/C#/WPF/EF Certifié MCP disponible sur Paris, province et pays limitrophes (enseignement en français uniquement).
    Mon blog : pragmateek.com

  3. #3
    Membre du Club
    Inscrit en
    Mars 2009
    Messages
    104
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 104
    Points : 69
    Points
    69
    Par défaut
    Merci beaucoup pour tes réponses, Pragmateek.

    Pour la table de référence, je vais passer à SQLite tout de suite histoire de limiter le travail plus tard.
    La base est OK pour le stockage après coup mais étant donné la spécificité de tes traitements tu ne devrais pas pouvoir en déléguer à la couche BDD, et de toute façon tu n'y gagnerais sûrement rien puisque locale.
    Je ne l'utiliserai donc que si je décide d'implémenter des sauvegardes des rapports d'analyse de texte. Par contre, je reste curieux de savoir quelle est la meilleure option parmi celles restantes.
    > Partir d'un string.split et remplir un tableau de string peu pertinent je crois
    > utiliser un regex pour les tâches du parseur (comptage global et mots uniques + split)
    Et/ou
    > un dataset
    > Une structure
    > autre chose que je ne connaîtrais pas
    J'exclus le stack et le dictionnary parce qu'il faut que j'associe une dizaine de propriétés maxi à chaque mot.

    Pour le background worker, je vais jeter un coup d'oeil à la doc. Si vous avez des exemples intéressants, je prends.

    Merci encore

  4. #4
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    Citation Envoyé par billybobbonnet Voir le message
    Par contre, je reste curieux de savoir quelle est la meilleure option parmi celles restantes.
    > Partir d'un string.split et remplir un tableau de string peu pertinent je crois
    > utiliser un regex pour les tâches du parseur (comptage global et mots uniques + split)
    Et/ou
    > un dataset
    > Une structure
    > autre chose que je ne connaîtrais pas
    J'exclus le stack et le dictionnary parce qu'il faut que j'associe une dizaine de propriétés maxi à chaque mot.
    Les Regex je ne pense pas que tu gagnes quoi que ce soit et :
    - tu risques même de perdre un peu en perf
    - ton code sera un peu obfusqué pour un novice (c'est un problème ou pas selon ton contexte)

    Donc un bon vieux Split des familles devrait faire parfaitement l'affaire.

    Pour le stockage des métadonnées je verrais bien un dictionnaire au contraire :
    - la clé serait le mot
    - la valeur une instance de ta structure stockant les statistiques de ce mot.

    Citation Envoyé par billybobbonnet Voir le message
    Pour le background worker, je vais jeter un coup d'oeil à la doc. Si vous avez des exemples intéressants, je prends.
    Voilà la structure d'une utilisation typique (peu de personnes le savent mais ça fonctionne parfaitement dans les applications console ) :
    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
    BackgroundWorker worker = new BackgroundWorker
    {
        WorkerReportsProgress = true,
        WorkerSupportsCancellation = true
    };
    worker.DoWork += (object sender, DoWorkEventArgs e) =>
    {
        for (int p = 0; p <= 100 && !e.Cancel; ++p)
        {
            //...
            (sender as BackgroundWorker).ReportProgress(p);
        }
    };
    worker.ProgressChanged += (object sender, ProgressChangedEventArgs args) => ... = args.ProgressPercentage;
    worker.RunWorkerCompleted += (object sender, RunWorkerCompletedEventArgs e) => ... e.Cancelled;
    worker.RunWorkerAsync();
    Les lambdas sont verbeuses volontairement (c'est extrait de mes formations .Net) mais si tu sais a quoi tu as à faire tu peux les raccourcir en omettant les types des paramètres qui seront inférés par le compilo.
    Formateur expert .Net/C#/WPF/EF Certifié MCP disponible sur Paris, province et pays limitrophes (enseignement en français uniquement).
    Mon blog : pragmateek.com

  5. #5
    Membre du Club
    Inscrit en
    Mars 2009
    Messages
    104
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 104
    Points : 69
    Points
    69
    Par défaut
    Pour le stockage des métadonnées je verrais bien un dictionnaire au contraire :
    - la clé serait le mot
    - la valeur une instance de ta structure stockant les statistiques de ce mot.
    En voilà une bonne idée

    Merci pour l'exemple du backgroundworker. Je vais partir de là.

    Je crois que je peux clore le sujet. Merci Pragmateek

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 11/03/2014, 13h37
  2. [XL-2010] Manipulation d'une chaine de caractères
    Par CristofMartins dans le forum Macros et VBA Excel
    Réponses: 9
    Dernier message: 07/05/2013, 15h14
  3. [MySQL] Manipulation d'une chaine de caractère.
    Par Tanoak_LaCapuche dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 23/07/2012, 09h01
  4. Réponses: 13
    Dernier message: 12/07/2012, 11h13
  5. Socket problème grosse chaine de caractère.
    Par jerem3000 dans le forum Débuter
    Réponses: 11
    Dernier message: 20/09/2011, 09h02

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