Wie am besten in großen Textdateien suchen?

  • Hallo,
    vermutlich ist die Frage, die ich habe ziemlich dumm, aber dennnoch stelle ich sie.
    Ich muss in größeren Textdateien (GPX-Datei, oft mehr als 100.000 Zeichen) die Werte der Longitude und der Latitude in jedem Trackpunkt ermitteln.
    Mein bisheriger Ansatz:
    Alles aus der Datei in einen String (zwischen) schaufeln, dabei die Zeilenden nicht mitnehmen.
    Dann alles über zwischen.indexOf(Zeichenfolge, Startwert) suchen.

    Code
    String TP_SEGSTART="<trkseg>",TP_PUNKTSTART="<trkpt",TP_PUNKTENDE="</trkpt>";
    String TP_LATSTART="lat=",TP_GAENSE=""",TP_LONGSTART="lon=";


    Erst nach TP_SEGSTART darf dann nach TP_PUNKTSTART gesucht werden.
    Erst hinter TP_PUNKTSTART dürfen dann die anderen Daten bis zum nächsten TP_PUNKTENDE genutzt werden.
    In diesem Bereich ist dann der Beginn von TP_LATSTART und TP_LONGSTART zu suchen, wobei die Reihenfolge nicht wirklich feststeht.
    Nach dem Startwert ist dann das betreffende Ende TP_GAENSE zu suchen und jeweils dann die Zahlenwerte dazwischen zu ermitteln.
    Dann den nächsten Trackpunktbeginn suchen über zwischen.indexOf(TP_PUNKTSTART, Startwert von gefundenem TP_PUNKTENDE +1) und dies dann bis zum Ende des ganzen Strings( > 100.000 Zeichen).


    Leider ist mit meinem Vorgehen die Zeitdauer bis zu 5 mal größer, als wenn ich die gleichen Daten auf dem gleichen Gerät mit einer anderen App (etwa OSMAnd) einlese.


    Wer kann mir helfen?
    Wo liegt mein Fehler?


    Fragenden Grüße,
    schymura :-/

  • Ich fürchte, Dein Fehler liegt darin, dass Du das Rad neu erfindest – und zwar achteckig. ;)


    Eine GPX-Datei ist zwar eine Textdatei, aber sie ist gleichzeitig auch eine XML Datei.
    Und eben solche XML Dateien lassen sich am Besten mit einem XML Parser abarbeiten.


    Eventuell kannst Du an Hand dieses Beispiels Deinen eigenen Parser bauen:
    http://www.vogella.com/articles/AndroidXML/article.html


    PS: OsmAnd nutzt, wenn ich den Quellcode richtig interpretiere, alles Mögliche mit C++ und hat für die Android App nur das UI mit Java implementiert.
    So schnell wie OsmAnd wirst Du die Datei mit Bordmitteln vermutlich nicht parsen können.

    Je mehr Käse, desto mehr Löcher.
    Je mehr Löcher, desto weniger Käse.
    Daraus folgt: je mehr Käse, desto weniger Käse.


    »Dies ist ein Forum. Schreibt Eure Fragen in das Forum, nicht per PN!«

  • Hallo Marco Feltmann,

    Zitat

    Ich fürchte, Dein Fehler liegt darin, dass Du das Rad neu erfindest – und zwar achteckig. ;)

    ja, da hast du wohl Recht! Diese Vermutung hatte ich ja auch schon, sonst hätte ich die Frage nicht gestellt.

    Zitat

    So schnell wie OsmAnd wirst Du die Datei mit Bordmitteln vermutlich nicht parsen können

    Na, gut, ich möchte schon bei Android bleiben und nicht noch mit C++ arbeiten....

    Zitat

    Eine GPX-Datei ist zwar eine Textdatei, aber sie ist gleichzeitig auch eine XML Datei.

    Der Link ist gut, werde ich mich wohl mal mit dem XmlPullParser beschäftigen, wenn GPX als XML betrachtet werden kann.


    Dankbare Grüße,
    schymura ^^

  • Hallo Marco Feltmann,
    nochmal danke, denn so habe ich mich nun mal mit dem XmlPullParser auseinandergesetzt.
    Zumindest glaube ich, dass ich die Klasse so in etwa verstanden habe.
    Leider aber kann ich sagen, dass selbst eine primitive Implementation, auch wenn sie nichts weiter macht, als den ganzen Text nach den TAGS duchzuscannen nicht schneller (sogar langsamer) arbeite, als mein "achteckiges Rad".
    Hier also die einfache Implementation.


    Du sieht, hier wird nur gescannt, nichts bearbeitet, keine einzige Rekursion ausgelöst etc. noch nicht einmal etwas in das Log ausgegeben ausser bei Dokumentstart und beim Dokumentende. Die unterschiiedlichen zu suchenden Zeichenfolgen im Trackpunkt, in dem ja auch noch viele andere Informationen (TAGS) stehen (können) wurden dabei überhaupt nocht nicht mit einbezogen....


    Wenn ich nicht einen großen Denkfehler mache ist XmlPullParser zwar eine mächtige Klasse, aber nicht wirklich schnell.
    Für weitere Anregungen bin ich immer offen.
    Schöne Grüße,
    schymura ^^

  • +hm+
    Unglücklicherweise schweigt sich die Dokumentation des XmlPullParsers darüber aus, ob der jetzt eher SAX oder eher DOM nutzt.
    Vielleicht ist die Klasse auch überladen? Oder es dauert wirklich sehr lange.
    (Im Fall des Parsers wird ja jedes Element durchgesprungen statt wie in Deinem achteckigen Rad nur das eine Element. Dein achteckiges Rad kann sich aber bei rtept und wpt verschlucken, der Parser nicht.)


    Ich habe einmal nachgeschaut und damals™ den DefaultHandler erweitert.


    Anstatt das Du dort in einer Schleife hantieren musst, werden Callback Methoden aufgerufen wenn die entsprechenden Ereignisse eintreten. In meinem Fall sind das:

    Java
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException;
    public void characters(char[] ch, int start, int length) throws SAXException;
    public void endElement(String uri, String localName, String qName) throws SAXException;


    Langsam war der auch, allerdings weil ich jeden gefundenen Wert dort in eine SQLite Datenbank via DAO geschrieben hatte.
    Ich hoffte eigentlich, dass es daran lag. Allerdings war meine Implementierung (speichersparend, leistungssparend) immer noch 5x langsamer als meine iOS Variante. C vs. Java halt. :(

    Je mehr Käse, desto mehr Löcher.
    Je mehr Löcher, desto weniger Käse.
    Daraus folgt: je mehr Käse, desto weniger Käse.


    »Dies ist ein Forum. Schreibt Eure Fragen in das Forum, nicht per PN!«

  • Hallo Marco Feltmann,
    danke für die Antwort.
    Ist es also anscheinend doch so langsam....

    Zitat

    Dein achteckiges Rad kann sich aber bei rtept und wpt verschlucken

    Nee, das tut es nicht, denn Waypoints etc. werden überhaupt nicht beachtet....
    Außerdem muss ich nicht voraussetzen, dass im Trackpoint Latitude und Longitude in "richtiger" Reihenfolge stehen. Höhe , Zeit etc, brauche ich aus dem Trackpoint auch nicht, denn ich wil den eingelesenen Track nur als Overlay einblenden.


    Schöne, dankbare Grüße,
    schymura ^^

  • Hallo Marco Feltmann,

    Zitat

    den Default Handler ausprobiert?

    die Frage war wirklich gut!
    Denn dadurch habe ich DefaultParser nun getestet und habe (für mich überraschend) festgestellt, dass er wirklich schnell arbeitet.


    Danke! Werde dann also nicht mehr durch die Gegend hoppeln, sondern mir schön rund mit dem DefaultParser die Gegend anschauen.....


    Schöne, dankbare Grüße,
    schymura

  • Das beruhigt mich.
    Fein fein. =)


    (Musste meinen Parser-Ansatz drei mal überdenken. Freut mich, dass dieser einigermaßen gut läuft.)

    Je mehr Käse, desto mehr Löcher.
    Je mehr Löcher, desto weniger Käse.
    Daraus folgt: je mehr Käse, desto weniger Käse.


    »Dies ist ein Forum. Schreibt Eure Fragen in das Forum, nicht per PN!«

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!