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

SWT/JFace Java Discussion :

Lister grosses quantités données dans une table


Sujet :

SWT/JFace Java

  1. #1
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2010
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 34
    Par défaut Lister grosses quantités données dans une table
    Bonjour,
    je suis en train de me poser une question d'architecture de mon prog.
    Je reçois une important quantité de données par TCP/IP, et j'affiche ces données (du log en gros). Mettons que j'en reçoive 500 à 1000 par secondes (1K/message), et que je limite l'affiche à 20 000 messages histoire de pas exploser la mémoire. Et je suis parti sur SWT/JFace pour mon GUI.

    Ma première idée:
    Un thread qui lit sur le socket, un thread qui fait le remplissage des TableItem d'une Table.
    Une Table, c'est sympa, par contre, si je dois faire du filtrage, faut que je me code pas mal de trucs. Sinon en perf, c'est pas trop mal.

    Autre idée:
    Un thread qui lit sur le socket, un thread qui remplit une liste d'Objets (MesMessages) et un TableViewer pour l'affichage.
    L'avantage du TableViewer est qu'il possède des outils de filtrage, par contre, je connais pas les perfs vs une Table classique.

    Autres idées?

    Que me conseilleriez-vous pour que mon prog consomme le moins de mémoire et de CPU (dans la mesure du possible) ?

    Merci
    Benoit

  2. #2
    Membre Expert
    Avatar de Gueritarish
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2007
    Messages
    1 800
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 800
    Par défaut
    Salut,

    La meilleure idée est, à mon sens, de passer par un TableViewer virtuel qui fait du lazy-loading. En gros, la seule différence pour toi, c'est qu'il faut donner au TableViewer le nombre d'Item dans la table et utiliser le style SWT.VIRTUAL.

    Voilà, à+
    Gueritarish

  3. #3
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2010
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 34
    Par défaut
    C'est effectivement impressionnant de rapidité.
    J'ai mis 1 000 000 d'items, rajouté un String de 200 caractères dans le modèle, et ça a mis moins d'1 s à s'afficher, et une occupation mémoire de 100MB.


    Allez, je vais l'implémenter de suite dans mon proj. Je posterai une évaluation des perfs pour clore le sujet.

    Merci !
    benoit

  4. #4
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2010
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 34
    Par défaut
    Je réagis au setItemCount dont tu parles pour sépcifier le nombre d'items dans la table.
    Cette table, je vais y ajouter les éléments 1 par 1 au fil de l'acquisition.
    Il faut appeler setItemCount à chaque fois ? en gros, on peut utiliser ce tableviewer de façon dynamique ?

  5. #5
    Membre Expert
    Avatar de Gueritarish
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2007
    Messages
    1 800
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 800
    Par défaut
    Pourquoi tu veux ajouter les éléments 1 par 1?
    Je me suis basé sur le Snippet que je t'ai envoyé et sur celui de SWT pour créer celui-ci... Si je peux ajouter 100 éléments toutes les 500ms et me payer le luxe de faire un sort sur tout ça, je pense que tu peux très bien les ajouter 1 par 1...
    Mais tu devrais peut-être attendre d'en avoir "assez" (je connais pas le besoin... mais 1 par 1 me paraît être un peu excessif pour une mise à jour).

    Voilà, à+
    Gueritarish
    Fichiers attachés Fichiers attachés

  6. #6
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2010
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 34
    Par défaut
    En fait, je me suis mal exprimé. En disant ça, je voulais dire que je ne sais pas combien je vais recevoir de données. Ca peut etre 1/s ou 1000/s. Désolé pour la confusion.

    Mais l'exemple Snippet151 me fait mieux comprendre comment ça marche. C'est très clair maintenant (et ultra simple...).

    Merci pour l'aide !

    Benoit

  7. #7
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2010
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 34
    Par défaut
    Re,
    j'aurai une tout dernière question:
    Dans mon cas d'utilisation, j'ai un TableViewer lié à une Table qui contient plusieurs colonnes (Time, origin, message)
    Est-ce que ILazyContentProvider supporte le fait que l'affichage se fasse sur plusieurs colonnes? (j'y arrive pas...)

    Merci
    benoit

  8. #8
    Membre Expert
    Avatar de Gueritarish
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2007
    Messages
    1 800
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 800
    Par défaut
    Attention, il ne faut pas confondre IContentProvider et affichage...
    Un IContentProvider (qu'il soit lazy ou non) va représenter le contenu de ton Viewer.
    Par contre, pour afficher les éléments contenus dans ton Viewer tu vas faire appel à des ColumnLabelProvider. Comme ça, tu indiques à chaque TableColumnViewer ce qu'elle doit afficher.

    N'hésite pas si tu as d'autres questions.

    Voilà, à+
    Gueritarish

  9. #9
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2010
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 34
    Par défaut
    Ok je comprends.
    Je vais clore le sujet car je pense que j'ai eu la réponse:
    utiliser un TableViewer pour l'affichage des mes logs. C'est rapide, et la conso mémoire est acceptable. En plus, les tableViewer offrent des fonctionalités de Filtering.

    Pour savoir comment utiliser correctement le TableViewer, je vais lire la doc en détail, ce sera mieux

    Merci
    Benoit

  10. #10
    Membre Expert
    Avatar de Gueritarish
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2007
    Messages
    1 800
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 800
    Par défaut
    Je te conseille plutôt lire le tutoriel de keulkeul sur le sujet...

  11. #11
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2010
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 34
    Par défaut
    Merci pour le lien, c'est très utile.

    Par contre, en parcourant le forum, je n'arrive pas à trouver un exemple qui explique proprement comment faire un update de la table. J'y arrive, mais je pense que ma méthode est crade.

    - J'ai un thread qui fait de l'acquisition et stock les data dans un tableau (un bête Message[])
    - J'ai un autre thread qui tourne infiniment (avec un sleep(100)), qui check si y a de la data dispo, et si oui, poste un display.AsyncExec() d'un Runnable qui refresh le table viewer.

    Pour faire le refresh du table viewer, je fais:
    m_logTableViewer.setInput(m_messages);
    m_logTableViewer.refresh();

    Questions:
    1- Est-ce que mon système de thread est clean ? (j'en doute)
    2- Le fait de faire un setInput à chaque refresh me parait douteux. Est-ce qu'il aurait pas une meilleure solution ? (car à partir du moment ou mon tableau atteint 100 000 messages, j'ai peur que ça sacade un max).
    Une sorte d'append pour éviter que le prog refresh toute la table, ce qui semble inutile...

    Merci

  12. #12
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2010
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 34
    Par défaut
    Bon finalement, j'ai utilisé la solution suivante:

    - Un thread d'acquisition qui remplit un tableau tampon
    - Un thread infini qui check si ya de la data dans ce tampon, et lance un un display.AsyncExec() d'un Runnable qui refresh le table viewer.

    Le refresh du tableviewer n'update que 1000 messages maxi pour ne pas freezer le GUI.

    Le tableViewer utilise un ILazyContentProvider et est de type SWT.VIRTUAL
    Example:
    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
     
    class MessageContentProvider implements ILazyContentProvider{
     
    		private Message[] elements;
    		private TableViewer viewer;
     
    		public MessageContentProvider(final TableViewer aViewer) {
                this.viewer = aViewer;
            }
     
    		@Override
    		public void updateElement(int index) {
    			viewer.replace(elements[index], index);
    		}
     
    		@Override
    		public void dispose() {
     
    		}
     
    		@Override
    		public void inputChanged(final Viewer aViewer, final Object oldInput,
    				final Object newInput) {
    		        this.elements = (Message[]) newInput;
    		}
     
    	}
    Le tableViewer contient des TableViewerColumn pour l'affichage.

    Resultat:
    J'affiche 50 000 messages (~600 caractères ) en 1s.
    Occupation mémoire: ~80MB

    Excellent!
    merci pour l'aide.

    Benoit

  13. #13
    Membre Expert
    Avatar de Gueritarish
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2007
    Messages
    1 800
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 800
    Par défaut
    Alors pour la mise à jour de tes données, il te faut passer par la méthode inputChanged de ton IContentProvider.
    Pour rappel: avec un TableViewer lazy, seul ce qui est à l'écran est "chargé". Donc, à mon avis, ton refresh ne se fait que sur les données affichées.

    Ensuite pour ce qui est de ta gestion des Thread, à la rigueur tu peux utiliser un pattern Observer/Observable (ou ) avec un Thread et un démon.

    Voilà, à+
    Gueritarish

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

Discussions similaires

  1. Problème de récupérations de données dans une table mysql
    Par Helpine dans le forum SQL Procédural
    Réponses: 3
    Dernier message: 09/03/2006, 20h07
  2. Réponses: 3
    Dernier message: 07/02/2006, 14h26
  3. [MySQL] Modifier une donnée dans une table
    Par leloup84 dans le forum PHP & Base de données
    Réponses: 27
    Dernier message: 02/02/2006, 14h25
  4. Inserer des données dans une table access SQL
    Par ouellet5 dans le forum Requêtes et SQL.
    Réponses: 1
    Dernier message: 23/11/2005, 22h11
  5. Réponses: 2
    Dernier message: 15/06/2005, 18h32

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