Performant einen batch von arrays halten, aktualisieren, ...
-
Nexus schrieb:
Aber was spricht dann gegen eine
std::queue<Datenblock, std::list<Datenblock> >?Was passiert da genau?
@Dravere
Es soll so aktualisiert werden:-recv-> 0 0 0 1 2 3 0 0 1 2 3 4 0 1 2 3 4 5Und zum Schluss hätte man dann die letzten drei empfangenen Arrays:
3: { 1, 2, 3, ..., 128 }
4: { 1, 2, 3, ..., 128 }
5: { 1, 2, 3, ..., 128 }
-
Anfänger04@AllesChillig schrieb:
@Dravere
Es soll so aktualisiert werden:-recv-> 0 0 0 1 2 3 0 0 1 2 3 4 0 1 2 3 4 5Und zum Schluss hätte man dann die letzten drei empfangenen Arrays:
3: { 1, 2, 3, ..., 128 }
4: { 1, 2, 3, ..., 128 }
5: { 1, 2, 3, ..., 128 }Ich verstehe nur Bahnhof. Vielleicht ein paar Worte mehr wären nicht schlecht ...
Was stimmt an meiner Lösung genau nicht? Die Reihenfolge, wie die Blöcke empfangen werden? Das könntest du ja auch selber noch abändern ...Grüssli
-
Anfänger04@AllesChillig schrieb:
Nexus schrieb:
Aber was spricht dann gegen eine
std::queue<Datenblock, std::list<Datenblock> >?Was passiert da genau?
Eigentlich das, was du geschrieben hast:
0 0 0 1 2 3 0 0 1 2 3 4 0 1 2 3 4 5Eine Queue ist eine FIFO-Warteschlange, bei der Elemente nur von hinten angehängt und von vorne entfernt werden können. Mehr Informationen...
-
@Dravere
Das würde dein Code machen:0
0
0Dann
1
0
0Dann
1
2
0Dann
3
2
0Dann
3
4
0...Es soll aber soooooooo sein:
#include <windows.h> #include <iostream> #include <deque> int main() { std::deque<int> queue(5, 0); for(unsigned i = 0; i < 14; ++i) { system("cls"); queue.push_back(i); queue.pop_front(); for(std::deque<int>::iterator it = queue.begin(); it != queue.end(); ++it) std::cout << *it << std::endl; Sleep(500); } }Führt es halt mal aus, sooooo meine ich es

Der Batch von Arrays darf natürlich nicht ein statisches Array mit fixer Größe sein, denn dann müssten ständig alle Elemente verschoben werden.
-> Vorne wird Eins weggenommen, hinten Eins dran. Somit bleibt die Größe des Batches immer gleich, die Daten sind immer in richtiger Reihenfolge da einfach AUFGESCHOBEN wird.
Aber ich möchte es ja NICHT so machen:
unsigned char data[128]; logSrv.read(data, 128); wasauchimmer.push_back(data);Denn so würde schon zweimal kopiert werden.
Es soll direkt wo reinkopiert werden und automatisch aufgeschoben werden.Ach ich glaub das gibts einfach nicht vorgefertigt...

-
Anfänger04@OkNochmal schrieb:
Ach ich glaub das gibts einfach nicht vorgefertigt...
Meine Güte, wie oft willst du meinen Vorschlag noch ignorieren?

-
1. Den Vorschlag von Nexus funktioniert ...
2. Mein Vorschlag funktioniert genauso, nur musst du halt die Reihenfolge beachten, aber das ist doch kein Problem! Die Reihenfolge kannst du immer über die Variablecurrentdefinieren. Und wenn du einen entsprechenden Iterator dafür brauchst, kannst du einen entsprechenden Wrapper dazu bauen, welche automatisch die richtige Reihenfolge kennt.
Ich seh dein Problem nicht ... und im übrigen bleibt die letzte Stelle bei meinem Vorschlag nicht unberührt!Grüssli
-
Nexus schrieb:
Meine Güte, wie oft willst du meinen Vorschlag noch ignorieren?

Aber ich weiß doch garnicht was du meinst!
Wie sollte ich mit einer std::queue ein doppeltes Kopieren verhindern?
Wie ich doch vorhin schon geschrieben habe, möchte ich DAS NICHT machen:unsigned char data[128];
logSrv.read(data, 128);
wasauchimmer.push_back(data);Wie denn sonst?
unsigned char data[128];
logSrv.read(queue.was?(), 128);
-
Dein Beispiel ÜBERSCHREIBT aber Werte. Es soll aber AUFGESCHOBEN werden.
Du hast ein statisches Array angelegt. Wie soll denn da aufgeschoben werden? Da müsste jedes Element verschoben werden.Bitte führ doch mal meinen Code aus, vorige seite Unten, das demonstriert wie die Daten gehalten werden sollen.

-
Anfänger04@Wasjetzt schrieb:
Dein Beispiel ÜBERSCHREIBT aber Werte. Es soll aber AUFGESCHOBEN werden.
Du hast ein statisches Array angelegt. Wie soll denn da aufgeschoben werden? Da müsste jedes Element verschoben werden.Mein Beispiel überschreibt Werte, das ist korrekt. Aber es überschreibt immer den ältesten Wert. Es werden, wie gefordert, immer maximal nur 10 Werte vorhanden sein. Zuerst werden sie einfach der Reihe nach reingeschrieben. Wenn man beim Letzten Ankommt, startet man wieder vorne in der Liste. Der erste Werte in der Liste, wenn der letzte beschrieben wurde, ist ja der älteste Wert.
So sieht es bei meinen Beispiel aus, wenn wir anstatt 10 Werte nur maximal 4 speichern würden:
0 0 0 0 -> Start: 0 1 0 0 0 -> Start: 1 1 2 0 0 -> Start: 2 1 2 3 0 -> Start: 3 1 2 3 4 -> Start: 0 5 2 3 4 -> Start: 1 5 6 3 4 -> Start: 2 5 6 7 4 -> Start: 3 5 6 7 8 -> Start: 0 usw.Start gibt jeweils den Index an, wo die Liste startet. Ist der gleiche Wert, wie current und bezeichnet zudem immer den ältesten Eintrag.
Grüssli
-
Du willst also so etwas:
int main() { std::deque<int> queue(5, 0); for(unsigned i = 0; i < 14; ++i) { queue.push_back(i); queue.pop_front(); for(std::deque<int>::iterator it = queue.begin(); it != queue.end(); ++it) std::cout << *it << std::endl; } }Das ist bis auf das Iterieren auch mit einer
std::queuemöglich. Die Queue ist halt darauf beschränkt, nur Zugriff auf das vorderste und hinterste Element zu bieten.Falls du iterieren musst, kannst du ja eine
std::listverwenden. Eine doppelt verkettete Liste kopiert intern nichts, da jedes Element Zeiger auf das nächste beinhaltet. Dann könntest du ebenfallspush_back()undpop_front()(oder umgekehrt) sowie bidirektionale Iteratoren anwenden.Edit: Eventuell wäre auch Boost.Circular Buffer etwas.
-
@Nexus
Nochmal, dies möchte ich verhindern:while(true) { unsigned char data[128]; logSrv.read(data, 128); }Wäre schon zu viel, weil data dann nochmals irgendwohin kopiert werden müsste.
Irgendwie so:while(true) logSrv.read(batch.Push(), 128);batch.Push() gibt einen Zeiger auf das Datenarray eines batch- Elementes zurück, welches automatisch erstellt und hinten angehängt wurde, während vorne Eins entfernt wurde.
read() schreibt dann automatisch in dieses Element und fertig.So soll es FUNKTIONIEREN. Irgendwie so...
-
Wäre schon zu viel, weil data dann nochmals irgendwohin kopiert werden müsste.
Was wird den da kopiert? Hast du überhaupt ein Ahnung, wie Array übergeben werden?
Und jetzt kommt das übliche:
http://en.wikipedia.org/wiki/Code_optimization#When_to_optimizeKnuth, Donald schrieb:
premature optimization is the root of all evil
(Jemand sollte da mal einen kurzten, verständlichen Artikel dazu schreiben, dass es jeder Anfänger versteht, warum man diesen Mist lassen sollte.)
Ansonsten suchst du wahrscheinlich am ehesten das hier:
http://www.cplusplus.com/reference/misc/iterator/back_inserter.html
-
Und was ist jetzt eigentlich an meiner Lösung falsch?
Ansonsten ist wirklich Boost.Circular zu empfehlen. Da gibt es zwar auch eine Kopie, aber was ist daran so extrem schlimm? 128 Bytes sind in 0.0000000000000...00000000000000001 ms kopiert.
Grüssli