
Ende letzten Monats begann 2GIS, Veranden auszustellen. Wir zeigen die Eingänge zu Organisationen seit 2013, und die Eingänge scheinen die gleichen Eingänge zu sein. Warum gerade jetzt? Alle internen Produkte und Prozesse sind fertig. Sie müssen lediglich etwas mehr hinzufügen und die Anzeige in der Benutzeroberfläche korrigieren.
Neben der Standardantwort „Es gab andere Prioritäten“ gibt es auch eine nicht ganz Standardantwort: „Es ist nicht so einfach.“ In diesem Artikel geht es darum, welche Schwierigkeiten es gab und wie wir sie gelöst haben.
Erstens ist der Eingang nicht der Eingang. So kann in einem Eingang mehrere Eingänge führen, meist von verschiedenen Seiten des Gebäudes. Die Definition des „(mehrstöckigen) Wohnblocks mit gemeinsamem Eingang“ ist ebenfalls falsch. Es kommt vor, dass ein Eingang in den ersten Stock des Eingangs und der andere in den zweiten und die folgenden Stockwerke führt.
Zweitens möchte ich nach Eingängen suchen.
Dies ist eine ziemlich gefragte Gelegenheit, da die Eingänge bei weitem nicht immer auf offensichtliche Weise angeordnet sind.
Zusätzlich zu den Eingangsnummern gibt es auch Namen (normalerweise aus einem einzelnen Buchstaben).
Oder auch wie
in Kaliningrad - genau der Treppe ist eine eigene Adresse zugeordnet.
Drittens haben wir beschlossen, dass wir, wenn wir nach Eingängen suchen, die Suche nach Wohnungsnummer nicht sofort unterstützen sollten. Sie entschieden - und sammelten die Wohnungen jedoch bisher ohne Bodenbindung. Wie bei Eingängen können Wohnungen nicht nur numerische Namen haben (meistens gibt es Varianten mit dem Buchstaben „a“), und die Bereiche sind bei weitem nicht immer durchgehend. In den alten Häusern von St. Petersburg ist die Nummerierung ziemlich seltsam: Die Wohnungen 1 und 3 können sich im selben Eingang befinden, und die Wohnung 2 kann sich im gegenüberliegenden Teil des Gebäudes befinden.

Lyrischer Exkurs zur DatenvalidierungVersuchen Sie nicht, die Validierung der gesammelten Daten sehr intelligent zu gestalten. In der nördlichen Hauptstadt gibt es Fälle, in denen Sie von mehreren Eingängen aus in eine Wohnung gelangen können. In einigen europäischen Siedlungen enthält die Adresse neben dem Haus den Namen des Eingangs und die Wohnungsnummer in diesem Eingang. Peter gefällt auch mit einem Gebäude mit zwei achten Eingängen.
Viertens möchte ich die Eingänge immer auf der Karte anzeigen, und nicht nur, wenn wir die Informationen eines bestimmten Hauses oder Eingangs studieren.
Und schließlich gibt es viele Eingänge - nach aktueller Schätzung gibt es allein in Moskau etwa hunderttausend davon. Die erste Bewertung „an den Fingern“ ergab einige astronomische Zahlen - wir haben alle sechs Male einen Fehler auf der größeren Seite gemacht.
Schlussfolgerungen:- Wir brauchen eine zusätzliche Einheit, die ihren eigenen Namen hat, eine Liste von Reihen von Wohnungen enthält und an die die Eingänge des Gebäudes angeschlossen werden können.
- Wir werden nach dieser Entität suchen und ihr eine separate Informationskarte zeigen.
- Wir sind gezwungen, entweder die von der mobilen Anwendung heruntergeladenen Daten noch einmal zu vergrößern oder diese Daten nur anzuzeigen, wenn eine Netzwerkverbindung besteht, oder uns etwas mit dem Format auszudenken.
Zur Lösung kommen
Die ersten beiden Punkte erfordern Änderungen sowohl an internen als auch an externen Produkten, dies ist jedoch eine Routine. Letzteres ist eine ganz andere Sache. Da wir Benutzer nicht gerne verärgern möchten, legen wir eine Einschränkung fest: Die Daten sollten offline verfügbar sein, und das Hinzufügen sollte die Größe der Datenbanken nicht erhöhen.
Wie? Einerseits müssen Sie die aktuelle Datengröße reduzieren, andererseits können Sie ein Format zum Speichern von Informationen über Eingänge erstellen, sodass die Menge zusätzlicher Daten minimal ist.
Datenvolumen reduzieren
Es gibt zwei Möglichkeiten, dies zu reduzieren:
- Schauen Sie sich die gespeicherten Daten genau an und versuchen Sie, etwas zu finden, auf das wir verzichten können.
- Überlegen Sie, ob es möglich ist, Daten effizienter zu speichern als jetzt.
Entwicklung des Datenspeicherformats vor der Ära der VerandenDie allererste und einfachste Option
Die herkömmliche Methode zum Speichern komplexer Daten besteht darin, sie zu
normalisieren , in eine Tabellendatenbank zu stellen und
Zusatzindizes zu erstellen. Einmal hat 2GIS genau das getan, außer um die Größe zu verringern. Der Inhalt jeder Tabelle wurde so sortiert, dass die Zellenwerte so oft wie möglich mit den Werten aus der vorherigen Zeile übereinstimmten. Wir haben die Spalten unabhängig voneinander gespeichert und Sequenzen mit identischen Werten reduziert.
Ein stark vereinfachtes Beispiel für die Optimierung der Lagerung eines Tisches mit Gebäuden:
Durch die Normalisierung können Sie die Redundanz reduzieren, aber es gibt auch eine negative Seite: Um ein UI-Element für ein Objekt zu bilden, müssen Sie mehrere Abfragen durchführen, die auf eine große Anzahl von Tabellen zugreifen. Zu dieser Zeit wurden diese Tabellen jedoch nicht nur verwendet, um Daten für die Anzeige zu erhalten, sondern für fast alle Aufgaben, einschließlich der Textsuche und verschiedener Arten der Reisesuche. Bei all diesen Aufgaben konnten wir durch normalisierte Daten nur die Menge der verarbeiteten Informationen reduzieren.
Die Daten zum Rendern der Karte hatten bereits ein eigenes Binärformat und wurden in einem separaten Block gespeichert. Allmählich haben wir separate Binärformate erstellt, um die Suche nach Wegbeschreibungen und Textsuchen zu beschleunigen. In der Datenbank blieben nur Informationen übrig, die zum Anzeigen von Objektkarten sowie zum Verknüpfen einiger Objekte mit anderen verwendet wurden.
Vereinfachen Sie die Arbeit
Wie können Sie die Arbeit mit Daten vereinfachen? Erhalten Sie alle zum Zeichnen einer Karte erforderlichen Daten auf einmal über die Kennung des Objekts. Da die
Online-Version bereits alle Daten von der
API für eine Anforderung im
JSON-Format empfängt, können Sie gleichzeitig die von allen unseren Produkten verwendeten Formate kombinieren.
Sowohl JSons zum Anzeigen von Karten als auch Mitteilungen müssen für eine begrenzte Anzahl von Objekten mit einer Leistung von mehreren Zehnern gleichzeitig empfangen werden. Es gibt jedoch Szenarien, in denen einzelne Attribute für große Stichproben bis zu Hunderttausenden gleichzeitig abgerufen werden müssen. Es ist logischer, solche Attribute in eine separate Entität mit einem separaten Speicherformat zu unterteilen - Eigenschaften. Eigenschaften können vom Typ sein und effizienter im Binärformat gespeichert werden.
Ein naiver Ansatz zum Speichern von json ist die Verwendung einer Schlüsselwertdatenbank. Nehmen Sie als Beispiel Moskau als das größte unserer Projekte. Selbst in der einfachsten Form - für jedes Objekt, das json selbst gespeichert ist, 8 Byte Bezeichner und ein Trennzeichen - benötigt das Verzeichnis 1,9 GiB. Die resultierende Größe ist fast sechsmal größer als die zuvor beschriebene Option, und dies ist immer noch ohne Bindungen und Eigenschaften.
Wir haben Objekte absichtlich aufgeblasen, indem wir sie mit Informationen über alles gefüllt haben, was zur Anzeige ihrer Karten erforderlich sein könnte. Sie müssen jedoch weiterhin Feldnamen, Anführungszeichen, Kommas und Klammern speichern.
Daten komprimieren
Normalisierung ist nicht der einzige Weg, um Redundanz zu beseitigen. Der zweite beliebte Weg ist die Komprimierung. Das lzma-Archiv unserer unglaublich dicken Datei benötigt nur 55 MiB.
Natürlich können wir dieses Format nicht direkt verwenden, da wir für den Zugriff auf ein beliebiges Objekt alle zuvor gespeicherten Daten entpacken müssen und lzma-Archive nicht sehr schnell entpackt werden.
Wie können wir einerseits einen schnellen Direktzugriff erhalten und andererseits durch Komprimieren der Daten die Größe des erforderlichen Speicherplatzes reduzieren? Die Antwort ist, Paginierung zu verwenden.
Nachdem die Daten paginiert sind, können wir sie einzeln komprimieren. Um auf einen beliebigen Ort zugreifen zu können, müssen wir die Seite entpacken und scannen. Dies ist jedoch viel schneller als das Entpacken und Scannen des gesamten Archivs.
In diesem Format werden alle Daten gespeichert - json'y, Beziehungen und Eigenschaften. Diese Daten müssen noch den Kennungen der Objekte zugeordnet werden. Für jeden Bezeichner müssen ein oder mehrere Paare
<Speichernummer, Datennummer im Speicher> gespeichert werden .

Alle Seriennummern, Offsets und Größen werden in einem komprimierten Format ähnlich
UTF-8 gespeichert, wobei kleine Werte nur ein Byte belegen. Dies ermöglicht es uns, die Größe von Links zu reduzieren, indem wir einfach den Inhalt von binären Repositorys sortieren, um die Häufigkeit des Auftretens zu verringern.
Einige Eigenschaften haben viele Frequenzwerte, und daher ergibt das Sortieren einen großen Größengewinn. Andererseits kann daher die Seriennummer der Daten nicht für alle Speicher übereinstimmen.
Weit davon entfernt, dass alle Objekte Daten in allen Speichern haben, ist das Speichern von Speichernummern effizienter als das Verweisen auf leere Objekte.
Beschleunigen Sie den Datenabruf
Das beschriebene Format hat ein Problem. Um die Nummer des Objekts zu finden, in dem die Indizes für den angegebenen Bezeichner gespeichert sind, müssen wir eine binäre Suche in den Daten des ersten Objekts ausführen. Dazu müssen Sie entweder 10,9 MiB in den Speicher laden oder 21 zusätzliche Messungen durchführen. Beide Lösungen sind für uns nicht geeignet. Daher reduzieren wir die Anzahl der Messwerte, indem wir Daten in einem Baum speichern.
Wir gruppieren Daten zu 32 Objekten und speichern in den Zwischenebenen 128 der ersten Bezeichner verschachtelter Knoten. Wir haben drei Ebenen des Baums hinzugefügt und die Anzahl der zusätzlichen Messwerte auf vier reduziert (unter Berücksichtigung des Caching zuvor gelesener Baumknoten sogar auf 1-3). Preis - etwas weniger als 400 KiB.
In dieser Phase können wir Beziehungen und Eigenschaften ziemlich effizient speichern, aber json nimmt viel Platz ein. Das ist klar. Je größer die Seite, desto mehr Objekte gelangen dorthin und desto besser kann der Komprimierungsalgorithmus feststellen, welche Informationen redundant sind. Auf der anderen Seite müssen wir jedoch mehr Arbeit leisten, um ein einzelnes Objekt zu lesen. Jsons sind ziemlich große Objekte, und daher gibt es nur sehr wenige davon auf einer Seite. Daher müssen Sie dem Algorithmus helfen, seine Arbeit besser zu erledigen.
Brechen Sie json in Teile
Erstens haben viele Objekte übereinstimmende Datenschemata, nur Attributwerte unterscheiden sich. Zweitens sind viele Attributwerte auch für Objekte mit unterschiedlichen Schemata gleich. Wir werden die Schemata und Attributwerte in separate Speicher unterteilen und JSons in der folgenden Form speichern: eine Verknüpfung zu einem Schema + Verknüpfungen zu Attributwerten.
In unserem Datenschema ist die Anzahl der Attributnamen begrenzt. Wir können sie also in einer separaten Datei ablegen und stattdessen die Nummer speichern. Wir werden auch einige weitere Änderungen vornehmen, wobei zu berücksichtigen ist, dass JSons immer Objekte sind.
Ja, wir haben unsere Daten im Wesentlichen selbst komprimiert, wodurch der Funktionsumfang des Algorithmus verringert wurde. Andererseits haben wir den Zugriff auf Daten erheblich verlangsamt, und der Algorithmus hilft immer noch dabei, ähnliche in der Nähe gespeicherte Werte zu komprimieren.
Wir haben die Seitengröße auf 1 KiB eingestellt und es stellte sich heraus, dass wir zwar das Format so optimiert haben, dass einerseits das Lesen nicht sehr langsam war und andererseits die Daten so gut wie möglich gepackt wurden, wir aber bereits die „optimierten Tabellen“ sowohl in der Größe als auch in der Größe umgangen haben für eine einfache Bedienung. Aber nicht umsonst war das alles! Der maximale Gewinn sollte aus der Komprimierung der Werte von Attributen, Eigenschaften und Schemata resultieren. Wir stiften zlib an und stellen sicher, dass das Lesen von Daten aus der Datenbank vor dem Hintergrund der restlichen Arbeit wenig Zeit in Anspruch nimmt. Mit dem Ergebnis zufrieden wechseln wir zu anderen Aufgaben.
Werde das Unnötige los
Wir beginnen zu reduzieren, indem wir nach Daten suchen, die Sie loswerden können. Es stellt sich heraus, dass wir während der Existenz des Formats gelernt haben, auf die größte Verbindung zu verzichten. Das sind 10% der Größe!
Der Code für diese Daten war noch gebunden, aber die notwendigen Änderungen sind ziemlich trivial. Bereits veröffentlichte Anwendungen können jedoch nicht einfach geändert werden. Wir bemühen uns, so lange wie möglich nicht nur rückwärts, sondern auch direkt kompatibel zu bleiben. Und wenn der erste jedem bekannt ist, denken viele glücklicherweise nicht an den zweiten. Wir sind gezwungen, dies zu unterstützen, da die Benutzer aus verschiedenen Gründen die automatischen Updates deaktiviert haben und es nicht eilig haben, auf eine neue Version der Anwendung zu wechseln.
Benutzerverteilung nach VersionGanz oben steht die Verteilung der Benutzer nach den neuesten Versionen der Android-Anwendung. Unten ist iOS.
Es ist leicht zu bemerken, dass Benutzer von iOS-Geräten viel schneller aktualisiert werden, aber selbst unter ihnen gibt es viele Benutzer älterer Versionen.
Wir veröffentlichen auch immer noch neue Daten für die eingefrorene Version für Windows Phone. Und obwohl WP8-Benutzer nur einen kleinen Teil unseres Publikums ausmachen, sind dies in absoluten Zahlen fast 200.000 pro Monat.
Wir haben seit langem einen Mechanismus, mit dem wir mehrere Datenformate erstellen und automatisch bestimmen können, welche Versionen welche erhalten sollen. Die Gelegenheit ist gut, aber Sie müssen noch lernen, wie Sie diese Formate entladen. Die erste große Aufgabe bestand darin, einen Dienst zu implementieren, der alle Daten empfängt und den neuen für das alte Datenbankformat und den alten für das neue herausfiltert.
Ein netter Bonus aus der geleisteten Arbeit ist die Reduzierung der Größe der monatlichen Updates, da sich die Remoteverbindung von Monat zu Monat stark geändert hat und die Größe der Diffs erhöht hat.
Wenn Sie sich die verbleibenden Daten ansehen, können Sie insgesamt die gleichen 10% herauspressen, der Preis wird jedoch unvergleichlich höher sein. Bisher haben wir beschlossen, nicht zu berühren.
Optimieren Sie das aktuelle Speicherformat
Wie oben geschrieben, haben wir 1 KiB-Seiten erstellt und nicht alle binären Repositorys gepackt.
Das erste, was wir tun, ist zu versuchen, auch Seiten mit Links zu packen und zu überprüfen, ob der Unterschied in der Geschwindigkeit des Datenempfangs im Bereich des Fehlers liegt.
Der nächste Punkt ist die Auswahl der optimalen Seitengröße. Je größer die Seite ist, desto effizienter werden die Daten komprimiert, aber desto langsamer werden die Daten abgerufen. Und wenn mit zunehmender Seitengröße die Zeit- und Speicherkosten linear ansteigen, wird der Gewinn immer weniger spürbar. Nach den Tests beschließen wir, die Größe auf 8 KiB zu erhöhen.
Die Auswirkung der Seitengröße auf große AuswahlenWenn erwartet wird, dass die Seitenvergrößerung kleine Auswahlen verlangsamt, werden große - aus Hunderten von Elementen - sogar beschleunigt. Dies bedeutet, dass Sie in guter Weise je nach Anwendungsfall der darin gespeicherten Daten unterschiedliche Größen für Speicher auswählen müssen.
Insgesamt können nur diese beiden Punkte die Basis um 18% reduzieren!
Ändern Sie das Komprimierungsformat
zlib ist natürlich ein Klassiker, aber
zstd bietet eine höhere Dekomprimierungsgeschwindigkeit bei einem höheren Komprimierungsverhältnis. Darüber hinaus können Sie mit zstd zunächst ein einziges Wörterbuch für alle verfügbaren Daten erstellen, diese dann einmal speichern und mit allen Seiten komprimieren. Auf diese Weise verlangsamen wir den Prozess des Erstellens einer Datei mit einer Datenbank erheblich, drücken jedoch weitere 8% aus.
Veranden hinzufügen
Einfacher Weg
Am einfachsten ist es, jeden Eingang zu einem separaten Objekt zu machen, sie separat zu indizieren (nach groben Schätzungen + 10% der Indexgröße) und ihre Geometrie separat in den Daten zum Zeichnen der Karte zu speichern.
Diese Methode erhöht die Basis um insgesamt 3%. In den vorherigen Phasen haben wir mehr als genug gewonnen, um uns zu beruhigen und mit den Eingängen nach dem üblichen Schema zu arbeiten, aber ... zum Zeitpunkt des Arbeitsbeginns waren wir uns nicht sicher, und die Arbeit an einem alternativen Format verlief parallel.
Detaillierte Bewertung für InteressierteVersuchen wir, die Zunahme der Größe des Pakets mit der Datenbank für jedes Objekt zu bewerten:
8 Bytes - Kennung,
6 Bytes - Anzahl der verwendeten Speicher (Daten + fünf Eigenschaften; Eigenschaften werden aus den Hauptdaten extrahiert und in binärer Form gespeichert, da sie häufig für eine große Anzahl von Objekten gleichzeitig benötigt werden).
3 Bytes - Index im Data Warehouse,
2 Bytes - Offsetdaten des Objekts,
5 Bytes - Datenwerte - 2 Bytes pro Schaltung, durchschnittlich 3 Bytes für Wohnungsinformationen (wir glauben, dass es viele Duplikate geben wird und die Daten selbst einmal gespeichert werden),
6 Bytes - Offset-Datenkoordinaten (andere Eigenschaften haben viele doppelte Werte und werden reduziert),
8 Bytes - Koordinatenwerte.
Insgesamt 38 Bytes pro Objekt. Im Fall von Moskau sind dies 4,5 MiB für mehr als 124.000 gesammelte Inputs.
Als nächstes müssen wir auch die Verbindung zwischen dem Haus und den Eingängen speichern, es sind 2,5 Bytes für jedes Wohnhaus und 8 Bytes für jeden Eingang. 1 weitere MiB.
Nun überlegen wir, wie viel dies alles auf der Karte kosten wird.
Zuerst müssen wir die Geometrie speichern. Bei Polylinien benötigt der erste Punkt immer 8 Bytes, und alle nachfolgenden werden als Unterschiede der erforderlichen Genauigkeit gespeichert. Hier sind wir mit der Genauigkeit auf Dezimeter zufrieden. Die meisten Eingaben bestehen aus zwei Punkten, die nicht sehr weit voneinander entfernt sind. Daher kann davon ausgegangen werden, dass die Geometrie selbst 10 Byte belegt. Insgesamt 1,2 MiB.
Wir müssen auch die Eingabe-ID und das Objekt mit seiner Geometrie verknüpfen. Ein Index ist der gleiche Binärspeicher wie alles andere, nur das Kommunikationsziel (1 Byte), die Schichtnummer (1 Byte) und die Objektnummer (3 Byte) werden gespeichert. Plus 8 Bytes pro Bezeichner sowie ein Schnellsuchbaum. Insgesamt weitere 1,5 MiB.
Wie bereits am Anfang des Artikels erwähnt, möchten wir die Eingänge ständig auf der Karte anzeigen. Der einfachste Weg, dies zu tun, besteht darin, eine weitere Ebene mit Punkten zu entladen. Sie können die Ebene jedoch auch mit Geometrien wiederverwenden und ein neues
Symbol erstellen, das das benötigte Bild anzeigt am letzten Punkt der Polylinie.
10% des Suchindex sind 5,9 MiB. Zusammenfassend erhalten wir 14,2 MiB, was nur etwas mehr als 3% entspricht.
Aktuelle Option
Anstatt die Eingänge zu indizieren und den Suchindex aufzublähen, suchen wir nach Häusern, markieren aber zusätzlich die Abfragewörter und wählen daraus Adressen (relevant für die Suche nach Eingängen in Kaliningrad), Eingänge und / oder Wohnungen aus. So haben wir am Ausgang die Hauskennung und eingegebene Textfelder, über die wir die Treppe finden müssen, die wir brauchen.
HinweisDies ist ein kontroverser Punkt. Auf der einen Seite können wir die Größe der Datenbank reduzieren, auf der anderen Seite wird das Eingabeformat eingeschränkt - die Eingänge werden nicht auf viele Anfragen übertragen, die mit einer ehrlichen Suche korrekt verarbeitet würden.
Anstatt einzelne Objekte zu entladen, fügen wir alle Informationen zu den Eingängen direkt in die Gebäudedaten ein.
Und schließlich übertragen wir einen Teil der Geometrien in das Verzeichnis.
Letzteres ist näher zu erläutern.
Erstens stellen wir fest, dass die meisten Eingaben zwei Punkte sind und dieselbe Länge haben. Solche Eingaben können in Form eines Punktes + einer Richtung gespeichert werden, d.h. Speichern Sie 1 Byte pro Eingabe.
Zweitens nehmen wir an, dass die meisten Häuser in modernen Städten typisch sind, daher werden die Verschiebungen der Punkte ihrer Eingänge relativ zum Mittelpunkt des Hauses bis zu einer Wende zusammenfallen.
Wir haben bereits die zentralen Punkte der Gebäude.
Was ist, wenn wir eine neue Eigenschaft für das Gebäude hinzufügen - seine ganzzahlige "Richtung" und für jede Eingabe zwei weitere - ganzzahlige Offsets in Dezimetern entlang und senkrecht zur Richtungslinie? Wenn man bedenkt, wie wir JSons mit Informationen speichern, belegt die Eingabegeometrie im Durchschnitt etwas mehr als zwei Bytes.Ein zusätzlicher Bonus ist, dass wir die Korrespondenz zwischen der Eingabe-ID und der Objektnummer nicht mehr in der Kartenebene speichern müssen, da sich die Geometrie im Verzeichnis befindet.Minus - der Code ist komplizierter geworden. Früher haben wir der Karte nur gesagt, dass "solche und solche Objekte anzeigen" sollen, und jetzt, wenn wir die Eingaben anzeigen, extrahieren wir diese Daten aus json und fügen der Karte dynamische Objekte hinzu. Hier ist nicht alles sehr beängstigend. Zum Zeitpunkt der Anzeige der Pfeiltasten der JSON-Eingaben haben wir bereits die entsprechenden Objekte, dh es ist nicht erforderlich, zusätzlich zur Datenbank zu wechseln. Mit den angezeigten Einstiegspunkten ist alles etwas schlechter - jetzt müssen wir im Hintergrund bestimmen, welche Häuser sichtbar sind, die Daten dieser Häuser aus der Datenbank herausziehen, JSons zerlegen und, wenn es Eingaben gibt, dynamische Objekte für sie erstellen.Hinweis. , , 0,2% (972 ).
Da wir bereits zusätzlichen Code geschrieben haben, um die Eingänge zu den Eingängen anzuzeigen, hindert uns nichts daran, Zweipunkteingaben in der Organisation im Verzeichnis zu speichern. Der Gewinn ist in diesem Fall gering, aber kostenlos.Wie viel hat es uns gegeben? Aus 3% wurden 0,5%. Wir hätten noch weniger tun können, aber wir haben Bezeichner in den Daten belassen (die ziemlich schlecht komprimiert sind), um die Verarbeitung von Benutzernachrichten über ungenaue Eingaben zu vereinfachen.Ergebnis
Wir haben eine große Anzahl von Eingängen hinzugefügt, während wir die Größe der Datei mit Kartendaten um 0,5% und die Größe der Datei mit den Verzeichnisdaten um 26,6% reduziert haben. Letzteres ist immer noch die größte unserer Dateien, aber es ist nur eine der vier „schweren“ Dateien, sodass sich die Gesamtänderung als bescheidener herausstellte - 10,1%.Die Eingänge sind noch nicht abgeholt. Die Größe der Stützpunkte wird im Laufe der Zeit etwas zunehmen (nach aktuellen Schätzungen wird das gleiche Moskau um 0,4% zunehmen), aber auf jeden Fall ist das Ziel, die Eingänge freizugeben, ohne die Größe zu erhöhen, mehr als erreicht.Was weiter?
Wenn wir über Verbesserungen bei Lebensmitteln sprechen, werden wir die Eingänge und Wohnungen in den Suchtipps sowie bei der Suche nach den Start- und Endpunkten der Suche nach Wegbeschreibungen unterstützen. Wir denken auch darüber nach, wichtige Eingänge zu Gebäuden (hauptsächlich in Einkaufszentren) wie Veranden anzuzeigen.In technischen Plänen werden mehrere Ideen überprüft, die zu einer weiteren Reduzierung der Dateigröße mit Referenzdaten führen können, und Sie müssen andere Dateien sorgfältig prüfen.Und natürlich werden wir die Fehler korrigieren, die wir bisher haben.Noch ein Gedanke: Verwenden Sie JSON mit Bedacht
Aus dem oben Gesagten ergibt sich die Schlussfolgerung, dass Sie nicht zu viel über Binärformate nachdenken und einfach JSON verwenden können. Dies ist nicht ganz richtig.
Das funktioniert bei uns, weil wir gleichzeitig mehrere zehn Objekte von der Kraft erhalten müssen. Außerdem verwenden wir Rapidjson, und es ist sehr intelligent und verbraucht wenig Speicher.Es lohnt sich auch, die Übertragung von JSON-Daten von C ++ auf die Benutzeroberfläche, die in einer anderen Sprache geschrieben sind, einzuschränken.Zuerst müssen Sie es in eine Zeichenfolge verwandeln.Zweitens werden die im UI-Teil verfügbaren Parser diese Zeile wieder zusammensetzen und dies viel langsamer tun.Es ist besser, alle Daten von JSON selbst abzurufen und einfache Schnittstellen zu verwenden, die so angepasst sind, dass bestimmte Elemente auf der Benutzeroberfläche angezeigt werden.