Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, syomin, Вы писали:
S>>1. Время обработки файла практически не зависит от того, где расположен обрабатываемый файл: на SDD и HDD. В обоих случаях время одно и то же. S>>Как можно объяснить такое поведение программы? Можно ли как-то увеличить скорость обработки не прибегая к многопоточности? S>У вас структура файла и задачи разработана без учёта реалий IO. S>Дело в том, что все современные устройства (включая SDD) — блочные. Т.е. прочитать из них 38 байт невозможно физически. При каждом чтении у вас с диска фактически читается блок минимального размера (если он не найден в кэше). Таким образом, вы гарантированно убиваете скорость чтения. S>Различия при работе в один или в два потока явно связаны с различиями Cache Hit Ratio — видимо, "второй" поток успевает почаще обратиться к окрестностям недавнего чтения "первого" потока, чем помогает работе.
S>Поэтому структуру файлов в СУБД, к примеру, последние 20 лет дизайнят на основе страничной организации, и стараются минимизировать количество затронутых страниц при выполнении популярных операций. А 38-байтные записи были типичны для ISAM-СУБД типа dBase, и вышли из моды ещё до 1995 года.
S>Увеличить скорость обработки будет можно, если вы постараетесь упорядочить доступ к файлу так, чтобы максимизировать "линейные чтения". Точнее советовать трудно, не зная деталей вашего алгоритма — зачем ему обходить записи в определённом порядке, и можно ли этот порядок хотя бы частично изменить.
Скажу честно, задача несколько оторвана от реальности, но мне она показалась интересной в качестве разминки для ума. Есть большой текстовый файл, в каждой строчке которого записан GUID. Файл настолько большой, что его невозможно загрузить в память целиком (даже если распарсить GUID'ы в System.Guid). Нужно вывести на экран все повторяющиеся GUID'ы, их по условию задачи очень мало.
Я решил её следующим образом. Файл обрабатывается в два прохода. При первом проходе из файла последовательно считываются все GUID'ы и для каждого из них считается хеш. В зависимости от значения хеш-суммы, GUID'ы распределяеются по "корзинам" — в одну корзину попадают GUID'ы с одинаковыми значениями хеша. В корзине сохраняется не сам GUID, а его порядковый номер в файле.
При втором проходе файл обрабатывается "покорзинно". Все GUID'ы, входящие в корзину, заново загружаются из файла в HashSet для поиска дубликатов.