Große JSON-Dateien schnell und effizient verarbeiten

Kenta1561

Bekanntes Mitglied
Hallo,

eigentlich versuche ich gerade eine Android-App zu machen, da es aber eher um allgemein Java und Performance geht, dachte ich, ich könnte auch mal hier fragen.

Es geht um folgendes: Ich benutzte eine offizielle API vom Frankfurter Flughafen, um Flüge von und nach Frankfurt zu bekommen. Das Problem bei der API ist jedoch, dass es nicht wie bei manchen anderen APIs die Möglichkeit gibt, die Zahl der Ergebnisse zu limitieren. Deshalb muss muss jedes Mal wenn die Anwendung gestartet wird insgesamt um die täglich 1300 Flüge gelesen werden, obwohl ich nur eigentlich um die 100-150 Flüge (also ungefähr im 2-stündigem Rahmen) brauche. Ich habe es hinbekommen, nur 100-150 Flüge anzuzeigen, jedoch ändert es nichts daran, dass trotzdem diese Massen an Flügen erstmal gelesen werden müssen. Wie kann ich das Ganze so optimieren, dass es schneller läuft? Oder geht es nicht?

Kenta1561
 
Naja, wenn die API nicht zulässt, dass weniger geladen werden, können nicht weniger geladen werden 😉

Wenn du in der Anwendung weniger brauchst, kann man die natürlich direkt im Service/Repo/'wie auch immer du das nennst' filtern, dann bekommt die restliche Application davon nichts mit
 
Also 1300 kommt mir jetzt nicht so wahnsinnig viel vor. Das sollte man doch in weniger als 1s geparsed haben.

Aber davon mal ab würde ich das Konzept eh ändern. Du hältst die Daten einfach lokal auf dem device und machst bei jedem Start der App einen Request im Hintergrund der die Flugdaten aktualisiert. Damit hat der User (ausser beim allerersten Start der App) überhaupt keine Wartezeit und kann sogar offline arbeiten wenn es nötig ist.

Gruß

Claus
 
@Thallius Stimmt, danke für die Idee 😀 Ich denke auch dass nicht das Parsen viel Zeit kostet, sondern das eigentliche herunterladen. (Wenn man im Playground von der API rumprobiert dauert das Laden sehr lange (es wird nicht geparsed sondern einfach als Text angezeigt))
 
Du kannst dir mit time in der Konsole ausgeben lassen, wie lange curl braucht, nen Browser dafür nutzen ist doch Unsinn...
 
Hallo,

danke für die ganzen Antworten. Ich habe gerade herausgefunden, dass die Verzögerung nicht am Herunterladen der Daten oder an der Visualisierung der Daten liegt, sondern am Lesen der JSON-Datei.
Ob ich erst mit OkHttp die Response mit body().string() in ein String umwandle oder erst im JsonReader mit new JsonReader(new InputStreamReader(body().byteStream()) ist egal, es dauert fast genau so lange.
Es wäre halt echt am besten wenn ich die Zahl der Flüge begrenzen könnte, leider geht das nicht. Weil es ja wie schon erwähnt bereits am Lesen liegt, bringt es auch nichts, beim durchgehen des Flüge-Arrays bzw. Entry-Sets zum Beispiel mit einem Integer-Counter bei 100 Flügen mit return abzubrechen. Die Idee mit den lokalen Daten ist eigentlich ganz gut, aber gibt es auch eine alternative, schnelle Möglichkeit wenn ich immer die Daten auf dem Bildschirm aktuell halten möchte?

PS:
Ich habe das sogenannte Streaming bei Gson gefunden, was angeblich nicht die komplette Datei erstmal lädt, sondern erst bei Bedarf. Ich bin mir ziemlich sicher dass dadurch die App schneller starten kann, jedoch
sind die Json-Antworten von der API so komisch gebaut (Manchmal nehmen sie wenn sie keine richtigen Werte als Antwort haben null als Value, manchmal lassen die die Tags auch komplett raus), dass es fast unmöglich scheint, durch next(), begin() und end() blind die ganze Json-Datei zu durchforsten.

Kenta1561
 
danke für die ganzen Antworten. Ich habe gerade herausgefunden, dass die Verzögerung nicht am Herunterladen der Daten oder an der Visualisierung der Daten liegt, sondern am Lesen der JSON-Datei.
Ob ich erst mit OkHttp die Response mit body().string() in ein String umwandle oder erst im JsonReader mit new JsonReader(new InputStreamReader(body().byteStream()) ist egal, es dauert fast genau so lange.
Wie lange dauert es denn überhaupt?

Ich habe das sogenannte Streaming bei Gson gefunden, was angeblich nicht die komplette Datei erstmal lädt, sondern erst bei Bedarf. Ich bin mir ziemlich sicher dass dadurch die App schneller starten kann, jedoch
sind die Json-Antworten von der API so komisch gebaut (Manchmal nehmen sie wenn sie keine richtigen Werte als Antwort haben null als Value, manchmal lassen die die Tags auch komplett raus), dass es fast unmöglich scheint, durch next(), begin() und end() blind die ganze Json-Datei zu durchforsten.
Ob die Tags vorhanden sind oder nicht oder null sind ist eigentlich egal, solange GSON das parsen kann, kann er es parsen - du nutzt doch jetzt schon GSON?
 
@mrBrown Eigentlich wollte ich mit gson.fromJson die Json-Datei parsen, jedoch wusste ich nicht wie ich zum Beispiel folgendes parsen sollte:

"codeShares": [
{
"codeShare": {
...
}
}, (usw.)

codeShare ist hierbei irgendwie doppelt? geschachtelt und ich weiß nicht wie ich das mit gson.fromJson() parsen kann. Deshalb habe ich immer nur mit
getAsJsonObject(), get(), getAsJsonArray() usw. die Json-Datei geparsed.

Kenta1561
 
Ne, da ist nichts doppelt, das heißt anders.

Generell nutzt man GSON, in dem man Klassen mit gleicher Struktur wie das JSON hat, in welches dann die Daten überführt werden.
In dem Fall halt ein Array von Objekte, aber der Ausschnitt ist etwa knapp und unvollständig, um da was zu sagen...
 
@mrBrown
Also, ich bin jetzt bis hierhin gekommen:

Die Variablen sind:
private OperatingAirline operatingAirline;
private AircraftType aircraftType;
private FlightNumber flightNumber;
private List<FlightNumber> codeShares;

"codeShares": [
{
"codeShare": {
"airlineCode": "LH",
"trackNumber": "9695",
"suffix": ""
}
},
{
"codeShare": {
"airlineCode": "NH",
"trackNumber": "5350",
"suffix": ""
}
},
{
"codeShare": {
"airlineCode": "TP",
"trackNumber": "8988",
"suffix": ""
}
},
{
"codeShare": {
"airlineCode": "UA",
"trackNumber": "7212",
"suffix": ""
}
}
]

Die Liste mit FlightNumber an sich wird normal gelesen, wenn ich die Größe von der Liste mir ausgeben lasse wird auch die richtige Größe genannt (4). Jedoch sind die Variablen der FlightNumber-Klasse alle null,
was darauf deutet, dass die Werte nicht richtig gelesen wurden. Ich verstehe jetzt aber nicht, wie, wo und welche Annotation ich hinzufügen muss.

Kenta1561
 

Zurück
Oben