2010-10-22 19 views
3

À l'origine, j'utilisais les méthodes d'analyse XML de RIM pour analyser un fichier texte de 150 ko, environ 5000 lignes de xml, mais cela prenait environ 2 minutes. :L'analyse d'un fichier texte sur BlackBerry prend une éternité

Titre: Titre du livre
ligne 1
ligne ligne 3

je devrais être capable de lire le fichier en moins de temps qu'il faut pour cligner des yeux, mais il est encore lent . Les livres d'identification sont des vecteurs d'objets et de lignes du livre sont stockés dans un vecteur de chaînes dans l'objet Livre.

class classs = Class.forName("com.Gui.FileLoader"); 
InputStream is = classs.getResourceAsStream(fileName); 

int totalFileSize = IOUtilities.streamToBytes(is).length; 
int totalRead = 0; 

//Thought that maybe a shared input stream would be faster, in this case it't not. 
SharedInputStream sis = SharedInputStream.getSharedInputStream(classs.getResourceAsStream(fileName)); 

LineReader lr = new LineReader(sis); 
String strLine = new String(lr.readLine()); 
totalRead += strLine.length(); 

Book book = null; 

//Loop over the file until EOF is reached, catch EOF error move on with life after that. 
while(1 == 1){ 

    //If Line = Title: then we've got a new book add the old book to our books vector. 
    if (strLine.startsWith("Title:")){ 

     if (book != null){ 
      books.addElement(book); 
     } 

     book = new Book(); 

     book.setTitle(strLine.substring(strLine.indexOf(':') + 1).trim()); 

     strLine = new String(lr.readLine()); 
     totalRead += strLine.length(); 
     continue; 
    } 

    int totalComplete = (int) ( ((double) totalRead/(double) totalFileSize) * 100.00); 
    _observer.processStatusUpdate(totalComplete , book.getTitle()); 

    book.addLine(strLine); 

    strLine = new String(lr.readLine(), "ascii"); 
    totalRead += strLine.length(); 
} 
+0

pour le shake de performance pourquoi ne pas le faire avec des fonctions traditionnelles seulement? par exemple. sans LineReader. Manipulation manuelle d'une boucle de lecture de caractères. –

Répondre

2

Il est facile de supposer que toutes les opérations que vous avez élidées de l'échantillon de code ont un temps constant. Je devine que l'un d'eux fait quelque chose inefficacement, tel que book.addLine(strLine); ou peut-être _observer.processStatusUpdate(totalComplete , book.getTitle()); Si ces opérations ne peuvent pas se terminer à temps constant, alors vous pourriez facilement avoir un algorithme d'analyse quadratique. Le simple fait de penser aux opérations est la meilleure façon de le comprendre, mais si vous êtes perplexe, essayez d'utiliser le profileur BlackBerry. Exécutez votre programme dans le débogueur Eclipse et faites-le s'arrêter à un point d'arrêt juste avant l'analyse. Ensuite, dans Eclipse, sélectionnez 'window .. show view .. autre .. BlackBerry .. BlackBerry Profiler View' Sélectionnez le bouton 'options d'installation' dans la barre d'outils de la vue profileur. Il a un triangle bleu dans l'icône. Définissez 'attribution de méthode' sur cumulatif, et 'quoi profiler' sur 'temps incluant les méthodes natives'

puis continuez votre programme. Une fois l'analyse terminée, vous devez interrompre l'exécution du programme, puis cliquer sur l'onglet 'méthode' de la vue du profileur. Vous devriez être capable de déterminer votre point de douleur à partir de là.

+0

Le bug était avec la mise à jour de statut de traitement et mon estimation est en attente pour synchroniser. Merci de votre aide! – SS44

0

Essayez d'utiliser new BufferedInputStream(classs.getResourceAsStream(fileName));

EDIT:

Apparemment, le documentation qui dit qu'ils ont BufferedInputStream est wrong.

Je vais laisser cette mauvaise réponse ici juste pour que les gens aient cette information (doc étant faux). Où le profileur vous dit-il que vous passez votre temps?

+0

BufferedInputStream ne semble pas disponible dans mon lot actuel d'API 5.0. Eclipse ne semble pas pouvoir le résoudre lors de la compilation. J'ai essayé d'utiliser ByteInputStream, mais pas de meilleur résultat final. – SS44

+0

Avez-vous BufferedReader disponible? – nos

+1

Ceci est J2ME - pas de telles classes –

0

Si vous n'avez pas de profileur préféré, il existe jvisualvm dans Java 6 JDK.

(Je pense que vous trouverez tout le temps dépensé sur le chemin vers le bas pour « lire un caractère à partir du fichier ». Dans ce cas, vous devez tampon)

4

D'une part, vous êtes lire dans le fichier deux fois - une fois pour déterminer la taille, puis à nouveau pour l'analyser. Puisque vous le lisez déjà dans un tableau d'octets pour déterminer la taille, pourquoi ne pas passer ce tableau d'octets dans un constructeur ByteArrayInputStream? Par exemple:

//Used to determine file size and then show in progress bar, app is threaded. 
byte[] fileBytes = IOUtilities.streamToBytes(is); 
int totalFileSize = fileBytes.length; 
int totalRead = 0; 

ByteArrayInputStream bais = new ByteArrayInputStream(fileBytes); 
LineReader lr = new LineReader(bais); 

De cette façon, il ne sera pas si le reste des cours de lecture du flux sont en train de lire un octet à la fois - il est tout en mémoire.

+0

Merci pour votre aide, les conseils code/code plus propre est toujours la bienvenue. – SS44