Как я могу получить доступ к данным во многих больших файлах CSV быстро от Perl?

Решение, которое мне особенно нравится, состоит в том, чтобы добавить весь файл в область удержания и заменить все новые строки в конце файла:

$ (echo foo; echo bar) | sed -n 'H;${x;s/\n//g;p;}'
foobar

Однако кто-то сказал мне, что пространство удержания может быть конечным в некоторых реализации sed.

7
задан brian d foy 25 July 2009 в 19:25
поделиться

5 ответов

Один раз проанализируйте данные и поместите их в базу данных SQLite . Запрос с использованием DBI .

9
ответ дан 6 December 2019 в 06:50
поделиться

ИМХО, самый простой способ разместить на диске очень большой хеш - использовать BerkeleyDB . Это быстро, проверено временем и надежно, а модуль CPAN предоставляет связанный API. Это означает, что вы можете продолжать использовать свой хэш, как если бы он был структурой данных в памяти, но он будет автоматически читать и записывать через BerkeleyDB на диск.

11
ответ дан 6 December 2019 в 06:50
поделиться

Крайне предпочтительно не извлекать весь список в память при каждом запуске скрипта. Использование базы данных на диске позволит вам сделать это. Если по какой-то причине вам нужно при каждом запуске касаться каждой записи в CSV-файле, я могу порекомендовать хранить ее на RAM-диске, а не на физическом. Очевидно, что он умещается в памяти, я не думаю, что вы добьетесь больших улучшений, изменив дисковый формат, в котором вы его храните. Единственный способ действительно ускорить его - сохранить на более быстром носителе.

2
ответ дан 6 December 2019 в 06:50
поделиться

Если вы только вам нужно получить доступ к части данных в каждом сценарии, а не ко ВСЕМ, DBM :: Deep , вероятно, ваш лучший выбор.

Диск / ввод-вывод, вероятно, будет вашим самым узким местом, независимо от того, что вы делать. Возможно, вы могли бы использовать поставщика данных, который хранит все данные, доступные в кэше mmapped - используя что-то вроде Sys :: Mmap :: Simple Мне никогда не приходилось делать такие вещи, поэтому я не Мне больше нечего предложить.

1
ответ дан 6 December 2019 в 06:50
поделиться

Что ж, я принял предложение Синан Унюра (спасибо!) И сделал База данных SQLite и повторно запустите мою тестовую программу, чтобы сравнить получение данных через файлы CSV с получением данных из базы данных SQLite:

$ c:/perl/bin/dprofpp.bat
Total Elapsed Time = 1705.947 Seconds
  User+System Time = 1084.296 Seconds
Exclusive Times
%Time ExclSec CumulS #Calls sec/call Csec/c  Name
 19.5   212.2 212.26 893448   0.0002 0.0002  Text::CSV_XS::fields
 15.7   170.7 224.45    126   1.3549 1.7814  DBD::_::st::fetchall_hashref
 9.14   99.15 99.157 893448   0.0001 0.0001  Text::CSV_XS::Parse
 6.03   65.34 164.49 893448   0.0001 0.0002  Text::CSV_XS::parse
 4.93   53.41 53.412 893574   0.0001 0.0001  DBI::st::fetch
   [ *removed the items of less than 0.01 percent* ]

Сумма для CSV_XS составляет 34,67% по сравнению с 20,63% для SQLite, что несколько лучше, чем решение Storable, которое я пробовал раньше. Однако это не совсем справедливое сравнение, поскольку с решением CSV_XS мне нужно загрузить весь CSV-файл целиком, но с интерфейсом SQLite я могу просто загрузить нужные мне части. Таким образом, на практике я ожидаю даже большего улучшения, чем показывает этот простой тест.

Я не пробовал использовать BerkeleyDB (извините, фридо) вместо SQLite, в основном потому, что я этого не делал. Я не видел этого предложения, пока не занялся опробованием SQLite. Настройка теста была нетривиальной задачей, поскольку мне почти никогда не приходилось использовать базы данных SQL.

Тем не менее, решение явно состоит в том, чтобы загрузить все данные в базу данных и получить доступ через модуль DBI. Спасибо всем за помощь. Мы очень ценим все ответы.

3
ответ дан 6 December 2019 в 06:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: