Welchen Containertyp verwenden
-
Hallo,
ich bin aktuell noch bei der Umsetzung meines UDP Multicast Projekts und auch wenn es soweit funktioniert würde mich interessieren wie der "richtige", bzw sinnvolle Weg die Speicherung vorzunehmen.
Aktuell habe ich eine Klasse "Client" angelegt in der die einzelnen Clients jeweils als Objekt der Klasse angelegt werden sollten. Die Klasse hat die Properties "name", "address" und "port" (String, String, Integer).
Wenn ich meine Anfrage ins Netzwerk schicke bekomme ich von den Clients eine Antwort die werte ich aus und erstelle entsprechend die einzelnen Clients (jede Antwort wird ein Client erstellt mit den übergebenen Werten).
Meine Frage ist welcher Datentyp sich für diese Nutzung am besten eignet bzw. was für die Praxis das sinnvollste ist.Ich hatte testhalber "QList<QObject*> " und "QVector<Client>" versucht die ich beide befüllen kann. Da die Objekte wärend der gesamten Laufzeit vorhanden bleiben sollen und erst beim neuen manuellen Start der Suche die Liste erst geleer wird (und mit den neuen Antworten gefüllt) wollte ich einfach mal fragen was denn der "richtige" Weg ist eine Menge "x" von Objekten zur weiteren Verwertung zu speichern.
Gibt es Vor- bzw. Nachteile die für oder gegen einen bestimmten Typ sprechen?
Mit freundlichen Grüßen
Marco
-
@Throndar said in Welchen Containertyp verwenden:
wollte ich einfach mal fragen was denn der "richtige" Weg ist eine Menge "x" von Objekten zur weiteren Verwertung zu speichern.
Das hängt stark davon ab wie die Elemente in dem Container benutzt werden. Und das ist etwas was aus dem Post nicht wirklich hervorgeht. Es gibt kein "richtig" für alle Use Cases. Wie willst du auf die Elemente zugreifen? Ich vermute, dass du einen bestimmten Client identifizieren musst, oder? Über einen Index? Über einen Namen? Über einen Hash?
Hier gibt es einige Informationen: http://doc.qt.io/qt-5/containers.html -
Hallo @jsulm,
erstmal danke für deine Antwort.
Im nächsten Step sollen die Clients (die ich aktuell in einer Tabelle anzeige) per Mausklick ausgewählt werden um eine Verbindung per Websocket zum entsprechenden Rechner aufzubauen. (um dann im Nachgang wenn eine Verbindung besteht z.B. Textnachrichten zu übertragen)
Dafür müsste ich auf das jeweilige Objekt zugreifen und die Properties die das Objekt beinhaltet (Name, Adresse, Port) zum Verbindungsaufbau weiter verwenden.
Nach dem Link wäre das QList an der Stelle auf Grund der Geschwindigkeitsvorteile und da ich nicht zwingend die aufeinanderfolgenden Speicherbereiche von QVector benötige die Containerklasse der wahl oder sehe ich das falsch?
Gruß
Marco -
@Throndar said in Welchen Containertyp verwenden:
Dafür müsste ich auf das jeweilige Objekt zugreifen
Genau. Die Frage ist aber: wie? Wie identifizierst du den Client? Anhand von welchen Kriterien?
-
hi @Throndar ,
wenn es darum geht sich zu entscheiden zwischen QList und QVector würde ich folgende Faustregel anwenden, zumindest mache ich das so.
Werden Elemente nach der ursprünglichen Initialisierung einzeln entfernt oder hinzugefügt, dann QList
Werden die Elemente nur ausgelesen oder manipuliert, dann QVector.Der Geschwindigkeitsunterschied ist merkbar!
In der selben Größenordnung, wenn nicht mehr, wie der Unterschied zwischen
at(x)
und[x]
-
Hallo @jsulm,
ich bin mir noch nicht sicher wie ich auf die Tabellenelemente zugreifen kann. Der Punkt wäre der nächste auf der Liste.
Als Möglichkeit zur Identifikation hatte ich überlegt ob ich nicht die IP Nummer, die ich ja in der Tabelle habe und diese ja einmalig ist, verwenden könnte.
In dem Fall würde ich das Objekt theoretisch finden wenn ich per Schleife den Vector/QList durchlaufe und die IP mit der angeklickten vergleiche... wie gesagt ich weiss aktuell nicht wie das möglich ist und ob überhaupt. Möglich wäre es auch eine Art ID im Objekt anzulegen zur Kennzeichnung der Clients, wo ich wiederrum auch nicht weiss ob ich in einer Tabelle dann mit dieser ID, die ich eigentlich nicht anzeigen wollen würde, etwas anfangen kann.Gruß
Marco
-
@Throndar said in Welchen Containertyp verwenden:
In dem Fall würde ich das Objekt theoretisch finden wenn ich per Schleife den Vector/QList durchlaufe und die IP mit der angeklickten vergleiche
Für so etwas würde ich einfach QMap nehmen (mit IP als Schlüssel), statt jedes mal zu suchen.
-
Hallo @J.Hilk,
vielen Dank für deine Rückmeldung und deinen Tipp.
Vielleicht kannst mir sagen weswegen du auf diese Art entscheidest , auf der Seite von QT wie jsulm gepostet hatte konnte ich nicht wirklich erkennen was nun der Vorteil der jeweiligen Elemente ist (QVector <-> QList), oder gibt es Möglichkeiten zur weiteren Nutzung die es besser/einfacher/sinnvoller machen oder Funktion die ggfls nur per Vector funktionieren.
Im Prinzip lasse ich den Vector bzw. die Liste ja nur neue Einträge hinzufügen wenn sich ein Client auf die Multicast Anfrage meldet. Entfernt werden diese erst wenn ich manuell eine neue Suche ausführen lasse, ansonnsten wird halt einzig aus dem QVector/QList vom jeweiligen ausgewählten Client die Eigenschaften gelesen.
-
@Throndar QList ist eine verkettete Liste, daher ist ein Zugriff über Index langsam, dafür aber einfügen/entfernen schnell.
QVector ist ein Array, deswegen ist Zugriff über Index schnell (O(1)), allerdings einfügen/entfernen langsam, da oft Speicher neu alloziert werden muss und im schlimmsten Fall der ganze Inhalt umkopiert. Das ist in dem Link den ich vorher geposted habe beschrieben. -
Hallo @jsulm,
danke für die Antwort aber eine Frage hab ich da jetzt...
@jsulm said in Welchen Containertyp verwenden:
Für so etwas würde ich einfach QMap nehmen (mit IP als Schlüssel), statt jedes mal zu suchen.
an der Stelle hast du mich jetzt verwirrt. Ich dachte bisher immer das QMap immer zwei Werte Paarweise speichert, das könnte ich für meine Clients bei drei Werten nicht nutzen.
Oder meinst du eine QMap nutzen in der die jeweiligen IP (String) und dazugehörige Indexnummer (Integer) des Vector<Client> hinterlegt ist um die Schleife zu sparen?
Gruß
Marco
-
@Throndar So etwas:
QMap<QString, Client> clients; // Oder QMap<QString, Client*> clients;
Hier QString ist der Schlüssel (IP, oder was auch immer) und Client ist die Structur/Classe die den dazugehörigen Client representiert. Ich wüsste nicht wieso das ein Vector<Client> sein sollte, es sei denn pro Schlüssel kann es mehr als einen Client geben (da kann man aber auch http://doc.qt.io/qt-5/qmultimap.html nehmen). Ich habe ja QMap vorgeschlagen, da man damit schnell einen Client anhand von einem Schlüssel identifizieren kann statt in einem QVector/QMap zu suchen. Eigentlich wäre QHash sogar noch efizienter. Hier http://doc.qt.io/qt-5/containers.html#algorithmic-complexity gibt es Details.
Wie schon vorher gesagt, welcher Container der richtige ist hängt vom Usecase ab. Unter anderem wie auf die Elemente zugegriffen werden soll. Man sollte also zuerst diese Frage beantworten, bevor man sich für einen Container entscheidet.