2016-04-11 5 views
0

У меня есть набор больших файлов (около 2 Гб). При попытке загрузить его (предположим, что правильно):Загрузка большого двоичного файла с 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 

Это возвращает ошибку wsfull. Kdb +, насколько я знаю, предназначен для использования в таких задачах.

Есть ли способ обработки больших файлов без исчерпания памяти (например, сохранение на диске, даже если оно медленнее)?

+0

Вы используете 32-битный kdb +? –

+0

Да. Это единственная версия, доступная здесь: https://kx.com/software-download.php –

+0

В этом случае вы не можете многое сделать, я боюсь. Из-за естественного ограничения 32-битного процесса он не может адресовать более 4 ГБ (на самом деле это всего 2 ГБ на Windows), и размер вашего набора данных, вероятно, достигает этого предела. –

ответ

3

Как упоминал Игорь в комментариях (и возвращаясь к теме вопроса), вы можете читать большой двоичный файл в кусках и записывать на диск по одному фрагменту за раз. Это уменьшит объем вашей памяти за счет замедления из-за дополнительных операций ввода-вывода диска.

Как правило, для потоковых потоков может быть сложнее обрезать, поскольку вы можете завершить фрагмент с неполным сообщением (если ваша точка фрагмента была произвольной, а сообщения были переменной шириной), однако в вашем случае у вас, кажется, есть сообщения с фиксированной шириной, поэтому конечные точки куска легче рассчитать.

В любом случае, мне часто полезно использовать цикл (/) и отслеживать свой последний известный (хороший) индекс, а затем начинать с этого индекса при чтении следующего фрагмента. Общая идея (непроверенная) была бы чем-то вроде

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] 

Это будет продолжаться до тех пор, пока последний хороший индекс не достигнет конца файла. Вы можете отрегулировать размер селектора соответственно в зависимости от ограничений памяти.

В конечном счете, если вы пытаетесь обрабатывать большие данные с бесплатной 32-битной версией, тогда у вас будут головные боли, независимо от того, что вы делаете.