S>Я решил её следующим образом. Файл обрабатывается в два прохода. При первом проходе из файла последовательно считываются все GUID'ы и для каждого из них считается хеш. В зависимости от значения хеш-суммы, GUID'ы распределяеются по "корзинам" — в одну корзину попадают GUID'ы с одинаковыми значениями хеша. В корзине сохраняется не сам GUID, а его порядковый номер в файле.
S>При втором проходе файл обрабатывается "покорзинно". Все GUID'ы, входящие в корзину, заново загружаются из файла в HashSet для поиска дубликатов.
Сделай Индексы по типу B+ деревьев.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, syomin, Вы писали:
S>Всем привет!
S>Достаточно большой файл (~1 Гб) читается блоками фиксированного размера (38 байт). Внутри файла блоки следуют друг за другом, но читаются в произвольном порядке. Каждый блок читается один и только один раз. Обработка блока в программе очень простая и занимает минимальное время.
S>Работа с файлом происходит напрямую через FileStream. Создание объекта выполняется так: S>
S>Явное указание размера блока и опции FileOptions.RandomAccess существенно ускорило обработку файла.
S>Чтение блока происходит так: S>
S>stream.Seek(position * 38, SeekOrigin.Begin);
S>var _buffer = new byte[38];
S>var n = stream.Read(_buffer, 0, _buffer.Length);
S>
S>В моём представлении, узким местом, определяющим скорость обработки, является дисковая подсистема. Результаты профилирования показывают, что основное время тратится на методы Read(72%) и Seek(20%). Но есть вещи, которые я объяснить не могу:
S>1. Время обработки файла практически не зависит от того, где расположен обрабатываемый файл: на SDD и HDD. В обоих случаях время одно и то же. S>2. Если сделать обработку файлов в 2 потока, то время обработки уменьшается в 1,5 раза. И по прежнему не зависит от того, где он расположен (SDD или HDD).
S>Как можно объяснить такое поведение программы? Можно ли как-то увеличить скорость обработки не прибегая к многопоточности?
1. Результаты теста у вас некорректные ибо как уже сказали файл кешируется.
2. Последовательное чтение на порядок быстрее чем рандомный доступ.
3. Seek это зло
4. Лучше всего читать файл последовательно в одном потоке блоками, а вот потом распределять прочитанные блоки по потокам для обработки.
Возможно это даже будет быстрее мапинга файл в памяти ибо вы раньше начнёте обработку ещё до того как файл будет полностью прочитан.
В целом читать весь файл в память можно конечно но лучше что бы это сделала сама OS а не вы, ибо если вы явно это будете делать то это может быть более медленым вариантом ибо выделение целого куска памяти может быть задачей не лёгкой для OS.
Здравствуйте, VladCore, Вы писали:
VC>mmf всегда был на 2 порядка и больше быстрее filestream. почему так тормозит filestream не скажу — не знаю. ваш кэп
всё зависит от конкретног сценария работы. в данном случае, если не будет своппинга, выигрыш на два порядка не исключён (за счёт того что не надо переключаться в kernel mode и обратно), если будет (а по условиям задачи именно так) — то обычный I/O быстрее. хотя у меня читалось в среднем 4 КБ за раз, так что надо пробовать. другое дело что в любом случае, произвольный доступ к диску — это на порядки медленней, чем последовательный, хоть с mmf хоть без них
Здравствуйте, Tom, Вы писали:
VC>>mmf всегда был на 2 порядка и больше быстрее filestream Tom>пруф в студию
для чистоты эксперимента сначала обсудим требования:
1. перфоманс стресс должен сравнить производительность mmf и filestream доступа к файлу размером 1 гиг.
2. свободной памяти при стрессе должно быть достаточно что бы закешировать (без использования буффередстрим) 1 гиг в памяти перед стрессом с помощбю файлстрима. свободной памяти должно быть достаточно что бы отобразить в озу 1 гиг с помощью ммф одним куском без использования свопа.
3. стресс должен выполнять рандом рид по 1/4/8/38 байт.
4. стресс должен выполнять пункт 3 в 1/2/4 потока.
Здравствуйте, VladCore, Вы писали:
VC>>>mmf всегда был на 2 порядка и больше быстрее filestream VC>для чистоты эксперимента сначала обсудим требования:
собственно ты описал единственный случай когда mmf может быть на пару порядков быстрее i/o. а как насчёт других случаев? например последовательное чтение мегабайтными кусками некешированного файла