Быстрое чтение файла (формат stream_lf)

Ищем способ ускорить чтение и обработку большого текстового файла (в основном csv; stream_lf).

Должен ли я обходить RMS? Решение может быть асинхронным или синхронным.

Текущая реализация является синхронной, но слишком медленной.

Реализация выполнена на HP Pascal и с использованием библиотеки времени выполнения Pascal (OPEN/READLN/EOF/CLOSE). Допускается обход библиотеки времени выполнения pascal.

Примеры могут быть на C или Pascal.


person Peter Hofman    schedule 13.12.2011    source источник


Ответы (4)


Для системного блока было установлено значение 32. Я попробовал SET RMS/BLOCK=32/BUF=8. Это уже дало улучшение.

[править: если нет настройки процесса, используется системная настройка. Таким образом, выполненный тест добавил буферы, но не увеличил их]

32 всего 16 КБ. Отлично для 1992 года, плохо для 2012. Если уже помогло большее количество буферов, то большие буферы, вероятно, помогут еще больше. Чем больше, тем лучше. Кратные 8 КБ могут помочь только дополнительно. Таким образом, попробуйте 128, а также попробуйте 255 на уровне процесса SET RMS. Если это приносит счастье, то вы можете адаптировать процесс для выбора собственных настроек RMS и не полагаться на настройки DCL.

Вызов RMS $GET обычно получает только одну запись, но вы можете «солгать» о файле с помощью SET FIL/ATTR=(RFM=UDF) или, возможно, (RFM=FIX,LRL=8192). Вы можете сделать это временно в программе, используя SYS$MODIFY. После этого вы можете читать большими кусками, но вашей программе нужно будет декодировать настоящие записи в поддельных записях. Это будет очень похоже на использование SYS$READ / SYS$QIOW (BlockIO), но соблюдение режима записи даст вам бесплатное «упреждающее чтение». Да, вы можете закодировать это самостоятельно с помощью aysnc IO, но это хлопотно.

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

Сколько данных в игре? десятки мегабайт или гигабайт> Будет ли кеш XFC изменяться, чтобы кэшировать его между экспортом и обработкой?

Встретила веселье groetjes. Хайн.

person Hein    schedule 13.12.2011
comment
Одна из проблем с производительностью была вызвана используемой мной библиотекой протоколирования, которая делала OPEN/EXTEND/WRITELN/CLOSE каждый раз, когда записывалась строка. Я удалил библиотеку и написал свою собственную, которая записывается в память и сбрасывается на диск после 512 строк. Это уже улучшило производительность. Журнал также очищается обработчиком ошибок пользователя. - person Peter Hofman; 17.12.2011
comment
Кроме того, я думаю, что производительность может улучшиться, если я буду использовать записи фиксированной длины и писать/читать большие блоки за раз. В основном это означает, что я буду дополнять каждую строку перед добавлением перевода строки. Таким образом, файл по-прежнему читается в Windows, но запись и чтение улучшаются. По сути, это та же идея, которую я применил к логированию, хотя это запись только в записи переменной длины. - person Peter Hofman; 17.12.2011
comment
Использование записей фиксированной длины с полями с разделителями фиксированной длины также сделает файл более читаемым при его вводе. Спасибо за идею использования записей фиксированной длины. - person Peter Hofman; 17.12.2011

Для последовательных файлов: просмотрите код WASD или VWCMS (см. http://www.vsm.co.au/wasd). Я знаю, что эти обходные RMS также в пользу скорости для веб-сервисов, но я не знаю, в каких источниках это делается. Для относительных файлов учитывайте последовательность. Записи могут быть несуществующими (пустыми?) Для проиндексированных файлов: НЕ ДЕЛАТЬ. Вместо этого используйте RMS из-за внутренней структуры (индексы переплетаются с данными в этих файлах. В новом/реорганизованном файле это нормально, но отсутствие обслуживания вызовет проблемы с доступом за пределами RMS)

person SYSMGR    schedule 10.10.2012

Хм, тут не так много конкретики.

Вы точно знаете, что RMS замедляет работу?

Сравните время обработки (IO, CPU, Elapsed) с SEARCH/STAT/WIN=0. Одним из признаков может быть низкий режим USER, высокий EXEC больше, высокий IDLE. Используйте MONI MODE или GETJPI с EXECTIM, USERTIM

Оптимальное чтение RMS через PASRTL или напрямую, вероятно, будет означать несколько больших буферов с упреждающим чтением, NO SHARING или совместное использование только для чтения.

Повторите попытку после: $ SET /RMS/BLO=127/BUF=8 ! $! Block=255 или 128 для последних версий OpenVMS (8.4 или 8.3+патчи)

ЕСЛИ много маленьких записей, а режим EXEC высокий, то может быть слишком много времени для входа и выхода из RMS для извлечения записей. В этом случае попробуйте C или COBOL прочитать файл без общего доступа. RTL (библиотека времени выполнения) для обоих будет использовать BLOCKIO, а не запись ввода-вывода, чтобы избежать накладных расходов RMS. Они по-прежнему учитывают параметры буфера RMS, упомянутые выше. Пытаться?

Удачи и... дайте нам знать, как вы разбираетесь? Некоторые номера до/после, возможно.

Привет, Хайн

person Hein    schedule 13.12.2011
comment
Я уже изменил способ открытия файла. Теперь он открыт без общего доступа, а не с общим доступом только для чтения. Я также немного поиграл с командой SET RMS. По умолчанию для процесса ничего не установлено. Для системного блока было установлено значение 32. Я попробовал SET RMS/BLOCK=32/BUF=8. Это уже дало улучшение. Во время мониторинга файла я обнаружил, что $GET считывает только AVG 57 байт за раз (возможно, это размер avg.record, нужно проверить). Интересно, может ли использование BLOCKIO помочь. Завтра надо проверить следующее. Или чтение нескольких строк для одного и того же элемента одновременно, а затем обработка их за один раз. Также возможно. - person Peter Hofman; 14.12.2011
comment
К вашему сведению, программа экспортирует и импортирует данные из системы. Экспорт собирает данные, после чего конвертирует и записывает их в CSV-файл. Импорт читает и обрабатывает строку за строкой. Это может быть причиной проблемы. Так что, я думаю, мне нужно сделать это по-другому. - person Peter Hofman; 14.12.2011
comment
Поскольку исполняемый файл запускается из сценария, я также буду использовать SET RMS /BLOCK=x /BUF=y вместе с улучшениями в исполняемом файле. - person Peter Hofman; 17.12.2011

Используйте C. Обход RMS.

fopen файл.

fseek для завершения.

ftell, чтобы узнать размер файла

malloc кусок памяти такого размера

прочитайте за один раз.

Можно предположить, что если ваш файл намного больше, чем ваш рабочий набор, подкачка может быть тем, что съедает ваши настенные часы.

person EvilTeach    schedule 14.12.2011
comment
Спасибо за ответ, EvilTeach. Ваше решение можно использовать, однако наши правила кодирования не поощряют смешивание Pascal с C. А поскольку остальная часть системы написана на Pascal (и для математики на FORTRAN, и совсем немного на C), я решил не использовать ваше решение. В любом случае спасибо за усилия. - person Peter Hofman; 17.12.2011