Решение, которое мне особенно нравится, состоит в том, чтобы добавить весь файл в область удержания и заменить все новые строки в конце файла:
$ (echo foo; echo bar) | sed -n 'H;${x;s/\n//g;p;}'
foobar
Однако кто-то сказал мне, что пространство удержания может быть конечным в некоторых реализации sed.
Один раз проанализируйте данные и поместите их в базу данных SQLite . Запрос с использованием DBI .
ИМХО, самый простой способ разместить на диске очень большой хеш - использовать BerkeleyDB . Это быстро, проверено временем и надежно, а модуль CPAN предоставляет связанный API. Это означает, что вы можете продолжать использовать свой хэш, как если бы он был структурой данных в памяти, но он будет автоматически читать и записывать через BerkeleyDB на диск.
Крайне предпочтительно не извлекать весь список в память при каждом запуске скрипта. Использование базы данных на диске позволит вам сделать это. Если по какой-то причине вам нужно при каждом запуске касаться каждой записи в CSV-файле, я могу порекомендовать хранить ее на RAM-диске, а не на физическом. Очевидно, что он умещается в памяти, я не думаю, что вы добьетесь больших улучшений, изменив дисковый формат, в котором вы его храните. Единственный способ действительно ускорить его - сохранить на более быстром носителе.
Если вы только вам нужно получить доступ к части данных в каждом сценарии, а не ко ВСЕМ, DBM :: Deep , вероятно, ваш лучший выбор.
Диск / ввод-вывод, вероятно, будет вашим самым узким местом, независимо от того, что вы делать. Возможно, вы могли бы использовать поставщика данных, который хранит все данные, доступные в кэше mmapped - используя что-то вроде Sys :: Mmap :: Simple Мне никогда не приходилось делать такие вещи, поэтому я не Мне больше нечего предложить.
Что ж, я принял предложение Синан Унюра (спасибо!) И сделал База данных 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. Спасибо всем за помощь. Мы очень ценим все ответы.