Как эффективно обрабатывать более 300 файлов одновременно в Scala - PullRequest
4 голосов
/ 14 ноября 2009

Я собираюсь сравнить около 300 двоичных файлов, используя Scala, байты за байтом, 4 МБ каждый. Однако, судя по тому, что я уже сделал, обработка 15 файлов одновременно с использованием java.BufferedInputStream отнимает у меня около 90 секунд на моей машине, поэтому я не думаю, что мое решение хорошо масштабировалось большое количество файлов.

Идеи и предложения высоко ценятся.

РЕДАКТИРОВАТЬ: Фактическая задача заключается не только в сравнении разницы, но и в обработке этих файлов в том же порядке последовательности. Допустим, мне нужно посмотреть на байт ith в каждого файла одновременно и перейти к (ith + 1).

Ответы [ 5 ]

6 голосов
/ 14 ноября 2009

Заметили ли вы, что ваш жесткий диск медленно испаряется при чтении файлов? Считывание, что много файлов параллельно - это , а не , что механические жесткие диски предназначены для работы на полной скорости.

Если файлы всегда будут такими маленькими (достаточно достаточно 4 МБ), я прочитал бы весь первый файл в память, а затем сравнил каждый файл с ним последовательно.

Я не могу комментировать твердотельные накопители, поскольку у меня нет непосредственного опыта с их производительностью.

2 голосов
/ 14 ноября 2009

Вы, действительно, совершенно облажались.

Посмотрим ... 300 * 4 МБ = 1,2 ГБ. Это соответствует вашему бюджету памяти? Если это так, непременно прочитайте их все в память. Но, чтобы ускорить процесс, вы можете попробовать следующее:

  1. Чтение 512 КБ каждого файла, последовательно. Вы можете попробовать читать от 2 до 8 одновременно - возможно, через Futures, и посмотреть, насколько хорошо оно масштабируется. В зависимости от вашей системы ввода / вывода, вы можете получить некоторую скорость, читая несколько файлов одновременно, но я не ожидаю, что она будет сильно масштабироваться. ЭКСПЕРИМЕНТ! ЭТАЛОН!

  2. Обработка этих 512 КБ с использованием Futures.

  3. Вернитесь к шагу 1, если вы не закончили с файлами.

  4. Получить результат обратно из обработки Futures.

На шаге 1, ограничивая параллельные чтения, вы избегаете перегрузки подсистемы ввода-вывода. Нажмите на нее как можно сильнее, возможно, чуть меньше, но определенно не больше.

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

1 голос
/ 14 ноября 2009

Если вы просто хотите посмотреть, совпадают ли они, я бы предложил использовать алгоритм хеширования, такой как SHA1, чтобы проверить, совпадают ли они. Вот некоторый Java-источник, чтобы это произошло

многие большие системы, которые обрабатывают данные, используют sha1 Включая NSA и git Просто более эффективно использовать хеш вместо байтового сравнения. Хэши также могут быть сохранены для дальнейшего просмотра, если данные были изменены.

Вот разговор Линуса Торвальдса специально о git, в нем также упоминается, почему он использует SHA1.

1 голос
/ 14 ноября 2009

Являются ли файлы одинаковым количеством байтов ?Если это не так, файлы можно сравнивать просто с помощью метода File.length(), чтобы определить предположение равенства первого порядка.

Конечно, вы, возможно, захотите сделать более глубокое сравнение, чем просто:файлы одинаковые? "

0 голосов
/ 14 ноября 2009

Я бы предложил использовать nio, если это возможно. Знакомство с Java NIO и NIO2 кажется хорошим руководством по использованию NIO, если вы не знакомы с ним. Я бы не советовал читать файл и делать побайтное сравнение, если вы это делаете в данный момент. Вы можете создать ByteBuffer для считывания порций данных из файла, а затем выполнять сравнения из этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...