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

Android Discussion :

Ecriture de données d'un .txt dans une arrayMap trop longue


Sujet :

Android

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2015
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2015
    Messages : 4
    Points : 2
    Points
    2
    Par défaut Ecriture de données d'un .txt dans une arrayMap trop longue
    Salut,

    Je suis sur ce problème depuis un petit moment et pas moyen de trouver la solution par moi-même ou avec l'aide de mon bon ami google !
    Alors pour résumer j'essaye de programmer une application qui récupère un fichier .txt (environ 3mo) dans assets et qui lit les lignes une a une de ce fichier (environ 234000).
    Chaque ligne se compose d'un mot suivie de sa classe grammaticale et d'un token, tout ca separé par le regex "-". ex: hello-N-T.
    Je souhaite grâce à ma classe WriteDictionnary enregistrer cela dans une ArrayMap avec le mot pour clé et la classe grammaticale et le token en valeur.
    (Si je fait cela c'est pour que la recherche soit extrêmement rapide ensuite et facile avec la clé ).

    Jusque la pas de soucis, ça marche. Mais mon problème c'est que ça marche mal, meme très mal !
    Plusieurs dizaine de minutes pour faire le traitement (j'ai pas attendu jusque la fin)...

    Qu'est-ce qui ne vas pas dans mon code ?

    Ma classe WriteDictionary :
    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
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
     
    package com.model;
     
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
     
    import android.util.Log;
     
    import com.diana.MainActivity;
    import com.diana.R;
     
    /***************************** IMPORT *****************************/
     
    public class WriteDictionnary {
     
    	/************ DECLARATIONS ***************/
    	private Dictionary dico;
    	private MainActivity mainActivity;
     
     
    	/************ CONSTRUCTOR ****************/
     
    	public WriteDictionnary(Dictionary dico, MainActivity mActivity){
    		this.dico = dico;
    		this.mainActivity = mActivity;
    		try {
    			FromTxtCreateDictionary();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    //	if(this.dico.getMap().get("hello").getToken() == null){
     
     
    	}
     
    	/************** METHODES *****************/
    	public void FromTxtCreateDictionary()  throws java.io.IOException{
     
            String mLine;
            String separator = mainActivity.getString(R.string.wordType_separator); 
            String[] SplitLine;
     
            BufferedReader reader =new BufferedReader(new InputStreamReader(this.mainActivity.getApplicationContext().getAssets().open("dictionary.txt")));
            mLine = reader.readLine();
     
     
    	        while (mLine != null) {
     
    	        	SplitLine = mLine.split(separator);        	
     
    	        	//Add word, wordType, token in the dictionary
    	        	this.dico.addWordsInMap(SplitLine[0],SplitLine[0],SplitLine[0]);
     
    	        	//Read the next line
    	            mLine = reader.readLine();
    	        }
    	        reader.close();
    	}   
     
    }
    et ma classe Dictionnary qui représente ma map:
    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
     
    package com.model;
     
    /***************************** IMPORT *****************************/
    import android.util.ArrayMap;
     
     
     
    public class Dictionary  {
     
    	/************ DECLARATIONS ***************/
    	private ArrayMap<String, WordFunction> map;
     
     
    	/************ CONSTRUCTOR ****************/
    	public Dictionary(){
    		this.map = new ArrayMap<String, WordFunction>();
     
    	}
     
     
    	/************** METHODES *****************/
    	/**
             * @brief Add received word and his word function (token+type) on the map.
             * @param word : word received (key).
             * @param token : token received (value).
             * @param wordType : type of the word received (value).
             */
    	public void addWordsInMap(String word, String wordType, String token){
    		this.map.put(word,new WordFunction(wordType, token));
    	}
     
     
    	/************* ACCESSORS *************/
    	public ArrayMap<String, WordFunction> getMap() {
    		return map;
    	}
     
    	public void setMap(ArrayMap<String, WordFunction> map) {
    		this.map = map;
    	}
     
    }

    Merci d'avance.

  2. #2
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 691
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 691
    Points : 20 222
    Points
    20 222
    Par défaut
    A mon avis ce qui prend du temps dans ton cas c'est le traitement sur la chaine et particulièrement le split.

    Essai de le remplacer par un mix de indexOf/lastIndexOf et substring.
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Android n'est pas mon domaine, mais sur le java en général, je recommanderais déjà

    • de commencer par compiler la pattern avant la boucle, compiler une pattern ça prends un peu de temps, même si c'est pas beaucoup.
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
       
      Pattern p = Pattern.compile(separator);
          while (mLine != null) {
              String[] SplitLine = p.split(mLine);
    • d'appeler this.dico.addWordsInMap(SplitLine[0],SplitLine[1],SplitLine[2]); plutôt que this.dico.addWordsInMap(SplitLine[0],SplitLine[0],SplitLine[0]);, car ça m'a l'air d'un bug :p
    • De montrer un peu cette classe WordFunction qui est instanciée 234000 fois. Voir vu que ça ne représente que 2 lettres, regarde si il est nécessaire d'en faire autant d'instanciations (26*26, ca ne fait que 676 combinaisons différentes...)

  4. #4
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par tchize_ Voir le message
    • de commencer par compiler la pattern avant la boucle, compiler une pattern ça prends un peu de temps, même si c'est pas beaucoup.
    Ca dépend.
    Je ne connais pas l'implémentation d'Android, mais sous Java standard la méthode split() est optimisée lorsqu'on lui passe un seul caractère non-interprété, et utilisera des indexOf pour découper la chaine...



    a++

  5. #5
    Expert éminent

    Avatar de Feanorin
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    4 589
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 4 589
    Points : 9 149
    Points
    9 149
    Par défaut
    Bonjour,

    Est ce que le traitement est threadé ?
    Responsable Android de Developpez.com (Twitter et Facebook)
    Besoin d"un article/tutoriel/cours sur Android, consulter la page cours
    N'hésitez pas à consulter la FAQ Android et à poser vos questions sur les forums d'entraide mobile d'Android.

  6. #6
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2015
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2015
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Tout d'abord merci à tout le monde pour les réponses aussi rapides c'est vraiment cool !

    Alors effectivement je m'étais déjà rendu compte que mon split ralentissait en le testant sans l'ajout à ma map.
    J'ai testé vos différentes solutions et c'est le indexOf avec substring qui marche le mieux ( environs 10 secondes pour juste récupérer et spliter ma chaîne de caractères). Merci grunk.
    La solution avec le Pattern de tchize_ améliore aussi grandement mon code mais un peu moins qu'avec le indexOf... J'avoue que je ne m'y connais pas trop avec cette classe j'ai juste appliquer (bêtement) la solution de tchize_ je vais me pencher un peu plus dessus pour comprendre ce qu'il en retourne.

    J'ai aussi enlevé ma classe WordFunction qui n'était pas tres utile, l'ajout d'un string à la place est beaucoup mieux !

    Par contre, une fois mon split remplacé, j'ai voulu rajouter tout ce beau monde dans ma map et là le temps de traitement est de nouveau super long ( 6 min 35 ) . C'est déjà un bon début par rapport a mes 35 minutes du début vous me direz :p

    Feanorin: non le traitement n'est pas threadé. Je voyais pas l'utilité ici, mais j'avoue que je ne suis pas encore au top au niveau thread et sur quand les utiliser ...

  7. #7
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Lancinbe Voir le message
    Par contre, une fois mon split remplacé, j'ai voulu rajouter tout ce beau monde dans ma map et là le temps de traitement est de nouveau super long ( 6 min 35 ) . C'est déjà un bon début par rapport a mes 35 minutes du début vous me direz :p
    Je ne connais pas l'ArrayMap d'Android, mais en lisant la javadoc cela ne me semble pas pour stocker un grand nombre de données : https://developer.android.com/refere.../ArrayMap.html

    Une simple HashMap serait peut-être préférable.


    a++

  8. #8
    Expert éminent

    Avatar de Feanorin
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    4 589
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 4 589
    Points : 9 149
    Points
    9 149
    Par défaut
    Feanorin: non le traitement n'est pas threadé. Je voyais pas l'utilité ici, mais j'avoue que je ne suis pas encore au top au niveau thread et sur quand les utiliser ...
    Simple.

    Si tu ne thread pas ce traitement cela sera fera dans le thread UI , donc tu va perdre tu temps sur l'affichage est faire ramé ton application, voir la faire planté via l'affichage du Force Close.

    Tu peux définir des priorité sur le Thread créer est le mettre en priorité MAX tu coup tu favorises les opérations(traitement) dans ce thread.

    Une simple HashMap serait peut-être préférable.
    Responsable Android de Developpez.com (Twitter et Facebook)
    Besoin d"un article/tutoriel/cours sur Android, consulter la page cours
    N'hésitez pas à consulter la FAQ Android et à poser vos questions sur les forums d'entraide mobile d'Android.

  9. #9
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 691
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 691
    Points : 20 222
    Points
    20 222
    Par défaut
    On peut même imaginer plusieurs threads en parallèle pour encore accélérer le traitement
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  10. #10
    Expert éminent

    Avatar de Feanorin
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    4 589
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 4 589
    Points : 9 149
    Points
    9 149
    Par défaut
    Responsable Android de Developpez.com (Twitter et Facebook)
    Besoin d"un article/tutoriel/cours sur Android, consulter la page cours
    N'hésitez pas à consulter la FAQ Android et à poser vos questions sur les forums d'entraide mobile d'Android.

  11. #11
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2015
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2015
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Alors pour ArrayMap j'avais résolu le soucis du manque de mémoire par une conversion de mes chaines de caractères en tableau de bytes. Ça aidait même en accélérant le processus .
    J'ai essayer HashMap à la place d'une ArrayMap et magie (ou optimisation ) le code tourne encore plus vite.

    J'arrive maintenant a faire mon écriture en une 20aine de secondes ce qui peut aisément être cacher par un chargement au début de l'appli. J'avais mis un écran de chargement en attendant l'écriture dans le thread Ui de mon fichier dans la map.
    Je vais quand même étudier les threads a fond pour améliorer encore un peu plus la bestiole et voir même enlever mon écran de chargement.


    J'aurai juste une ou deux question pour la culture : pourquoi le substring avec indexOf marche mieux qu'un split ? Et totalement ailleurs est-ce que si j'avais utiliser les bases de données sqlite embarqué sur l'application au lieu d'un traitement par fichier, j'aurais pu attendre de meilleurs résultats ?


    Merci a tous c'est vraiment cool, je met un résolu !!

  12. #12
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    split utilise des expressions régulières. On peut ainsi couper sur des formules bien plus complexes qu'un seul caractère. La contrepartie, c'est que les algorithmes derrière sont plus lents. Faire un indexOf nécessite de faire N comparaisons et on a la valeur. Si ta chaine fait 10 caractères et que le séparateur est à l'index 4, e, 4 comparaisons, tu as ta valeur. LE substring derrière se contente de faire une copie partielle d'un tableau de petite taille, c'est très rapide. On peux difficilement couper de manière plus efficace.

    La contrepartie, c'est qu'avec cette méthode tu ne peux pas dire 'je veux couper sur toutes les virgules ou les point-virgule' par exemple.

  13. #13
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2015
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2015
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Merci Tchize pour l'explication

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

Discussions similaires

  1. Passage à la ligne dans une option trop longue
    Par PP(Team) dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 27/01/2011, 12h37
  2. charger les données d'un fichier .txt dans une table
    Par lemerite dans le forum Développement
    Réponses: 6
    Dernier message: 10/09/2008, 18h33
  3. [VB]stocker des données de pages web dans une base
    Par tofito dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 15/02/2006, 11h02
  4. Données contenant un apostrophe dans une colonne
    Par david71 dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 13/09/2005, 17h02

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