2016-04-11 17 views
0

Ich habe eine Reihe von großen Dateien (etwa 2 GB). Wenn ich versuche, es zu laden (lassen Sie uns das richtig übernehmen):Laden einer großen Binärdatei mit kdb + (Q)

ctq_table:flip `QTIM`BID`OFR`QSEQ`BIDSIZE`QFRSIZ`OFRSIZ`MODE`EX`MMID!("ijjiiihcs";4 8 8 4 4 4 2 1 4) 1: `:/q/data/Q200405A.BIN 

Es ein wsfull Fehler zurückgibt. Soweit ich weiß, sollte Kdb + für solche Aufgaben verwendet werden.

Gibt es eine Möglichkeit, große Dateien zu verarbeiten, ohne dass der Arbeitsspeicher erschöpft ist (z. B. das Speichern auf der Festplatte, auch wenn es langsamer ist)?

+0

Verwenden Sie 32-Bit-kdb +? –

+0

Ja. Das ist die einzige Version, die hier verfügbar ist: https://kx.com/software-download.php –

+0

In diesem Fall können Sie nicht viel dagegen tun Ich habe Angst. Aufgrund einer natürlichen Beschränkung eines 32-Bit-Prozesses kann es nicht mehr als 4 GB (in Wirklichkeit sind es nur 2 GB unter Windows) adressieren, und Ihre Datenmenge erreicht wahrscheinlich dieses Limit. –

Antwort

3

Wie Igor in den Kommentaren erwähnt (und zurück zum Thema der Frage) können Sie die große Binärdatei in Blöcken lesen und einzeln auf Platte schreiben. Dies reduziert Ihren Speicherbedarf auf Kosten der Geschwindigkeit aufgrund der zusätzlichen Festplatten-E/A-Vorgänge.

Im Allgemeinen kann Chunking für Bytestreams komplizierter sein, weil Sie einen Chunk mit einer unvollständigen Nachricht beenden könnten (wenn Ihr Chunk-Punkt willkürlich war und die Nachrichten variable Breite hatten). In Ihrem Fall scheinen Sie also Nachrichten mit fester Breite zu haben Die Chunk-Endpunkte sind einfacher zu berechnen.

In beiden Fällen finde ich es oft nützlich, mit over (/) zu loopen und den letzten bekannten (guten) Index zu verfolgen und dann beim Lesen des nächsten Chunks mit diesem Index zu beginnen. Die allgemeine Idee (ungetestet) wäre so etwas wie

file:`:/q/data/Q200405A.BIN; 
chunkrows:10000; /number of rows to process in each chunk 
columns:`QTIM`BID`OFR`QSEQ`QFRSIZ`OFRSIZ`MODE`EX`MMID; 
types:"ijjiiihcs"; 
widths:4 8 8 4 4 4 2 1 4; 
{ 
    data:flip columns!(types;widths)1:(file;x;chunkrows*sum widths); 
    upsertToDisk[data];  /write a function to upsert to disk (partitioned or splayed) 
    x+chunkrows*sum widths  /return the rolling index of the starting point for the next chunk 
    }/[hcount[file]>;0] 

Dies wird fortgesetzt, bis der letzte gute Index das Ende der Datei erreicht. Sie können die Chunkrows-Größe entsprechend Ihren Speicherbeschränkungen anpassen.

Schließlich, wenn Sie versuchen, mit der kostenlosen 32-Bit-Version mit großen Daten umzugehen, dann werden Sie Kopfschmerzen haben, egal was Sie tun.

Verwandte Themen