stream processing - read from stdin
-
Hi,
ich moechte daten die ueber cin (z.b.: file...) kommen an meinen algo zu verarbeitung senden.
aufgerufen wird es so:
cat huge_file_to_process | ./big_data_processing_engine -n 1 -n ... # of threads
wie lese ich ab besten stream_buffer_size - blocks von der stdin in meinen vector<char> ein? der stream_processing algo nimmt dann den ersten block, verarbeitet ihn und liest dann den naechten block von der stdin solang nichts mehr gelesen werden kann...
unsigned total_read = 0; int stream_buffer_size = 256; do { std::vector<char> buffer(stream_buffer_size); cin.read(&buffer[0], stream_buffer_size); total_read = cin.gcount(); stream_processing_algo(buffer, total_read); }while(total_read > 0);
-
for(std::vector<char> Buf(256, char()); std::cin; std::cin.read(&Buf[0], 256), stream_processing_algo(Buf, 256));
?
-
das alles in eine for schleife zu geben sieht ja unschoen aus?
ist folgender code schneller? und woher weiss ich wie viele zeichen von cin gelesen werden konnten?
std::copy_n(std::istream_iterator<BYTE>(std::cin), 256, std::istream_iterator<BYTE>(), cipher_text);
-
algoman1 schrieb:
ich moechte daten die ueber cin (z.b.: file...) kommen an meinen algo zu verarbeitung senden.
aufgerufen wird es so:
cat huge_file_to_process | ./big_data_processing_engine -n 1 -n ... # of threads
wie lese ich ab besten stream_buffer_size - blocks von der stdin in meinen vector<char> ein?
.. am besten: gar nicht!
Besser Du arbeitest direkt auf dem Stream (hier
cin
), dann kannst Du Dir den ganzen Vektor sparen.
Was macht dennstream_processing_algo
?
-
hi,
der algo rennt einen verschluesselung's algo. wie meinst du das mit direkt am stream arbeiten?
-
Der iterater verwended auch etwa gleich viel speicher wie der vector?
Was ist der vorteil wenn is direkt am input stream arbeite? Ich muss das ergebnis dann auf stdout ausgeben....
-
Algoman1 schrieb:
Der iterater verwended auch etwa gleich viel speicher wie der vector?
welcher Iterator?
Algoman1 schrieb:
Was ist der vorteil wenn is direkt am input stream arbeite? Ich muss das ergebnis dann auf stdout ausgeben....
zunächst braucht man keine Kopie der Daten. Dann kann man sofort mit der Interpretation anfangen, ohne auf den Rest der Zeichen zu warten und zum Dritten stellt die IO-Lib von C++ einiges für die Interpretation zur Verfügung; warum sollte man das nicht nutzen.
Kommt natürlich drauf an, um was es sich handelt.Was ist das für ein Ver-( oder Ent-?)schlüsselungs-Algorithmus? Wie viele Zeichen benötigt der auf einmal, um mit der Ent-(oder Ver-)Schlüsselung zu beginnen?
-
mit cin.read kann ich ja den buffer in einem vector kopieren, welches am stack angelegt wird waehrend dessen der iterator ja am heap arbeitet?
so ist cin.get + buffer am stack (vector<char>) schneller oder?
-
@Werner Salomon: meine folgenden iteratoren...das ist doch was du gemeint hast?
std::istreambuf_iterator<char> eos; // end-of-range iterator std::istreambuf_iterator<char> it (stream_buffer_size); // stdin iterator while (it!=eos) { unsigned int total_read = cin.gcount(); if(total_read > 0) { stream_processing_algo(it, total_read); } }while(total_read > 0);
-
gcount wird in der Regel nicht das tun, was du denkst. Mach es doch wie andere (STL-)Algorithmen es (aus guten Gründen) machen:
algorithmus(anfang, ende)
, stattalgorithmus (anfang, anzahl)
. Das ist viel universeller. Ich wette, du brauchst bestimmt nicht die Anzahl der Zeichen im Voraus zu kennen.Falls in dem Stream irgendwelche Daten stehen, die du danach wieder Stream-artig verarbeiten möchtest, bietet es sich auch an, das Ganze als einen streambuf zu implementieren. Guck mal hier:
http://www.c-plusplus.net/forum/p2228469#2228469
Ist da zwar nur XOR, aber dies ist nicht sehr komplex auf Blockchiffres erweiterbar (ein bisschen komplex aber schon).
-
algoman1: Das ist ein weit verbreiterter Denkfehler. Häufig höre ich Fragen wie diese. Also wie kann ich die Daten in einen Puffer lesen, damit ich sie verarbeiten kann statt sie Zeichenweise direkt aus dem Stream zu verarbeiten. Also eher so etwas wie:
stream_processing_algo(*it);
Wobei dann der Iterator überflüssig wird:
char ch; while (std::cin.get(ch)) stream_processing_algo(ch);
Benötigt dein stream_processing_algo einen Kontext, also mehrere Zeichen auf einmal, dann sollte er das intern handhaben und einen geeigneten Puffer verwalten.