Performanceproblem bei Dateiarbeit

perian

Mitglied
Hiho Forum.
Das ist meiner aller erster Forumpost - also seid zärtlich. :D

Ich code mir zur Zeit eine kleine Bibliothek zusammen bei der ich sehr viel wert auf das Design und weniger auf die Performance achte. Nun habe ich aber einen Code produziert, der so langsam ist, dass es fast intolerable ist. Leider hab ich keine Ahnung warum er so langsam ist. Wenn jemand eine Ahnung hat, wär ich sehr dankbar für Feedback.

Dieser Code beschäftigt sich mit dem einlesen von Dateien die biologische Sequenzinformationen enthalten. Die Dateien haben folgende Struktur:

>sequenz_identifier1 | annotation11 | annotation12
ACTGACGTATGACAG.....
>sequenz_identifier2 | annotation21 | annotation22
GTCGTAGCACGTACGA........
Wem das etwas sagt - es geht um Fasta-Dateien.

Java:
public class FastaFileIterator implements Iterator<Sequence> {

    private BufferedReader file;
    boolean hasNext = false;
    
    public FastaFileIterator(String name) throws IOException{
        this.file = new BufferedReader(new FileReader(name));
        int key = 0;
        
        
        //sets the reader to the start of the first sequence
        while((key = file.read()) != -1){
            if((char)key == '>'){
                hasNext = true;
                break;
            }
        }

    }

    public boolean hasNext() {
        return hasNext;
    }

    public Sequence next(){
        String id = "";
        String sequence = "";
        String headerLine = "X";
        this.hasNext = false;
        
        try {
            int key = 0;
            while((key = file.read()) != (int)'\n'){
                headerLine += (char)key;
            }
            
            while((key = file.read()) != -1){
                if(key != '>'){
                    if(key != '\n' && key != ' '){
                        sequence += (char)key;
                    }
                }else{
                    hasNext = true;
                    break;
                }
            }
            // Split the header-line into its parts
            String[] splittedLine = headerLine.split("/|/");
            
            // delete the leading ">"
            id = splittedLine[0].substring(1);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new Sequence(id,sequence);
    }

Dieser Code ist Teil einer Iterator-Klasse, die bei Aufruf von next, nach und nach alle Sequenzen als Sequenz-Objekte zurückgeben soll. Die Sequenz-Klasse muss an dieser Stelle nicht weiter interessieren.

Bei einem Testlauf mit einer Datei, die 200k Sequenzen enthält, brauchte mein Rechner erheblich länger, als ein "grep -c '>' test.fasta" Aufruf unter Linix. Wir reden hier wahrscheinlich um einen Faktor größer 100. Genaue Messungen sind an dieser Stelle nicht wichtig.

Woran kann das liegen? Ist mein Code extrem-unperformant? Ist das der OOP-Overhead? Ist es die Tatsache, dass ich noch einige kleinere Nebenoperationen mache, die grep nicht machen muss?

Für Inspiration bin ich sehr dankbar. Wenn ihr mehr Informationen braucht, lasst es mich wissen. Es ist mein erster Post und ich hab mit sowas keine Erfahrung. :D

Danke im Voraus.
 

perian

Mitglied
Hmmm. Ich benutze normalerweise auch readLine(). Es ist nur erheblich schwieriger das gleiche mit readLine zu realisieren.

Ist readLine wirklich wesentlich schneller als read?
 
G

Gast2

Gast
Zeichen einzeln einzulesen ist sehr langsam.
Entweder liest du ganze Zeilen ein, oder wenn die Datei größer wird ganze blöcke mit je nen paar kb größe.
 

Marco13

Top Contributor
Einzelne Zeichen in einer Schleife an einen String hängen ist ggf. auch ein Killer. Besser StringBuilder und immer sringBuilder.append(zeichen) ...
 

Wildcard

Top Contributor
Einzelne Zeichen in einer Schleife an einen String hängen ist ggf. auch ein Killer. Besser StringBuilder und immer sringBuilder.append(zeichen) ...

Genau das wird hier das Problem sein, denn der BufferedReader puffert sowieso schon, daher ist es auch ok Zeichenweise zu lesen, solange man dann nicht diese Form der Strink Konkatenation verwendet :)
 

Ähnliche Java Themen

Neue Themen


Oben