Нужен совет по эффективности: сканирование 2 очень больших файлов информации - PullRequest
2 голосов
/ 09 февраля 2010

У меня довольно странный вопрос.

У меня есть файл длиной 6 гигабайт. Что мне нужно сделать, это сканировать весь файл, построчно, и определить все строки, которые соответствуют номеру идентификатора любой другой строки в файле. По сути, это похоже на анализ файла веб-журнала, в котором есть много идентификаторов сеансов, которые организованы по времени каждого клика, а не по идентификатору пользователя.

Я пытался сделать простую (тупую) вещь, которая заключалась в создании 2 программ чтения файлов. Тот, который сканирует файл построчно, получая идентификатор пользователя, а затем 1. убедитесь, что идентификатор пользователя еще не обработан и 2. Если он не был обработан, прочитайте каждую строку, которая начинается с идентификатора пользователя, содержащегося в файл и хранилище (некоторое значение X, связанное со строками)

Какой-нибудь совет или советы о том, как сделать этот процесс более эффективным?

Ответы [ 6 ]

4 голосов
/ 09 февраля 2010
  • Импорт файла в базу данных SQL
  • Использовать SQL
  • Производительность!

Серьезно, вот и все. Базы данных оптимизированы именно для такого рода вещей. Кроме того, если у вас есть машина с достаточным объемом оперативной памяти, просто поместите все данные в HashMap для упрощения поиска.

3 голосов
/ 09 февраля 2010

Самый простой: создайте модель данных и импортируйте файл в базу данных, используя преимущества JDBC и SQL .При необходимости вы можете (если формат файла довольно специфичен) написать какую-нибудь Java, которая будет импортировать построчно с помощью каждой из BufferedReader#readLine() и PreparedStatement#addBatch().

Самое сложное: напишите свой код Java, чтобы он без необходимости не сохранял большие объемы данных в памяти.Затем вы в основном заново изобретаете то, что уже делает обычная база данных.

1 голос
/ 09 февраля 2010

Для каждой строки R в файле {

  1. Пусть N будет число, которое вам нужно выписка из R .

  2. Проверьте, существует ли файл с именем N . Если нет, создайте его.

  3. Добавить R в файл с именем N

}

0 голосов
/ 09 февраля 2010

Многие другие советы здесь хороши, но предполагают, что вы сможете загружать то, что вам нужно, в память, не исчерпывая ее. Если бы вы могли сделать это, это было бы лучше, чем решение «наихудшего случая», о котором я упоминаю.

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

Я бы предложил:
1. Откройте оба файла и прочитайте первую запись
2. Проверьте, есть ли у вас идентификаторы и обрабатываются ли они соответствующим образом
3. Прочитайте файл (ы) для только что обработанного ключа и повторите шаг 2 до EOF.

Например, если у вас был ключ 1,2,5,8 в FILE1 и 2,3,5,9 в FILE2, вы бы:
1. Откройте и прочитайте оба файла (FILE1 имеет ID 1, FILE2 имеет ID2).
2. Процесс 1.
3. Считать ФАЙЛ1 (ФАЙЛ1 имеет ИД 2)
4. Процесс 2.
5. Считайте ФАЙЛ1 (ID 5) и ФАЙЛ2 (ID 3)
6. Процесс 3.
7. Прочитайте ФАЙЛ 2 (ID 5)
8. Процесс 5.
9. Считайте ФАЙЛ1 (ID 8) и ФАЙЛ2 (ID 9).
10. Процесс 8.
11. Считайте ФАЙЛ1 (EOF .... больше не обрабатывается ФАЙЛ1).
12. Процесс 9.
13. Считайте ФАЙЛ2 (EOF .... больше не обрабатывается ФАЙЛ2).

Имеет смысл?

0 голосов
/ 09 февраля 2010

Вы не упоминаете, является ли это регулярной, постоянной или случайной проверкой.

Рассматривали ли вы предварительную обработку данных? Непрактично для динамических данных, но если вы можете отсортировать их по интересующей вас области, это значительно облегчит решение проблемы. Извлечение только тех полей, которые вас интересуют, может также уменьшить объем данных до более управляемого размера.

0 голосов
/ 09 февраля 2010

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

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

...