Pull to refresh

Comments 18

По-моему целесообразно убрать лидирующие нули в таблицах и отображать время в миллисекундах.

Согласен, исправлю чуть позже

Я все ждал, когда же в статье будет сравнение RandomAccess и SequentialScan, но его нет :(
Кстати, размеры буферов для чтения тоже влияют на производительность.


Сравнение количества потоков и используемого API (синхронное против асинхронного) лишь показывает, что мы в итоге упремся в ограничение роста производительности, т.е. закон Амдала. (кстати, тесты с 64/128/256 потоками наглядно это демонстрируют).

1. ScenarioAsync2 00:00:00.0670000 в SSD для Минимальный размер файла (байты): 1001 почему не жирное?
2. Сравнение миллисекунд — неблагодарное дело. Было бы здорово, если бы тесты работали хотя бы секунду, а то и десяток.
3. OOM не должно быть ни при каком раскладе. Вы складируете всё прочитанное в память? Тогда на время повлияет уборка мусора. Может быть, стоит складировать всё время в один и тот же byte[], если не ReadAllText?
4. Для больших файлов, разбросанных по диску (видео, например), последовательное чтение должно быть существенно быстрее на HDD, в предположении о дефрагментированном харде.
5. Использование существующих файлов на харде — плохая идея, имхо. Доступы к ним со стороны системы непредсказуемы. Лучше создать некоторую тестовую папку с таким набором файлов, который Вам интересен. Минус в том, что они все создаются примерно одновременно и вряд ли оказываются размазанными. Но, с другой стороны, в реальных условиях программа тоже устанавливается за ограниченное время.
  1. Моя промашка, абсолютно согласен, спасибо!
  2. "Сравнение миллисекунд" — да, согласен. Результаты у меня стабильно воспроизводились, потому я оставил именно миллисекунды.
  3. И всё-таки, он получался. По моим предположениям (субъективным), всё это было от большого числа запущенных операций (и большого размера файлов), т.е. все объекты были действительно достижимы. Вы правы, для избежания подобного поведения стоило как минимум обрабатывать файлы блоками (например, используя Microsoft.IO.RecyclableMemoryStream. Здесь же моя идея была следующая: сравнить скорость, используя простую логику чтения (т.е. ту, которую чаще всего будет использовать разработчик при стандартных задачах чтения с диска). Я уверен, что при разработке IO-bound приложений используется немало оптимизаций, все они за рамками моих замеров
  4. Я запускал дефрагментацию заранее на HDD. Если есть силы и время — Вы можете запустить тест на своем компьютере, для этого достаточно сделать git pull и запустить проект TestHost. У меня теория не воспроизвелась.
  5. Возможно. Моё основное предположение — сделать замер скорости чтения случайного набора файлов. Т.е. когда они обновляются в разное время, а значит дефрагментация может постепенно разнести их по диску.
В асинхронных тестах вы открываете файл с помощью вызова File.OpenRead(), а этот вызов создаёт FileStream в синхронном режиме. В итоге тестируется работа ThreadPool, а не асинхронного ввода-вывода. Попробуйте повторить асинхронные тесты, создав явно FileStream с параметром useAsync = true.

Интересный момент, окей, проверю чуть позже

а ответа нет? удалось проверить?

Если вы не знакомы с BenchmarkDotNet — самое время познакомиться. Скорее всего, при общей простоте использования, он более грамотно замерит "миллисекунды". И — нет, я не Андрей Акиньшин. :)

У меня вот похуже задача сейчас есть… Надо не просто много файлов быстро прочитать, а перебрать содержимое папки со подпапками, причем внутри более миллиона файлов. Процесс занимает более получаса.
Задача в том, чтобы найти новые файлы (которых еще нет в базе) и посчитать для них хеши по алгоритму. Но всё упирается именно в задачу перебора всех файлов в папке, чтобы найти именно новые
Можно сделать отдельный каталог для появления новых файлов, из которого скрипт будет переносить в каталоги с кучей файлов попутно отмечая в базе.
Так мне не надо в реальном времени-то! Просто иногда запускаю процесс, который перебирает файлы и добавляет в базу новые, но далеко не каждый день это требуется делать.
Ну даже если использовать FileSystemWatcher — мне это не особо поможет, т.к. программа же все равно не будет знать о том, что между ее запусками какие-то файлы в папке поменяли/добавили. Т.е. мы опять возвращаемся к тому, что надо перебрать весь список файлов во всех подпапках папки, а этот процесс занимает более получаса — причем без чтения содержимого файлов! Фактически, мне нужно имя, путь и размер файла. При этом я уже и так отказался от использования FileInfo, оказалось, что для определения размера быстрее всего — открыть файл на чтение, как-то так:

using (var file = new FileStream(fn, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
    return file.Length;
}


Судя по коду FileInfo, она запрашивает больше данных о файле и сильнее грузит жесткий диск в итоге, что при миллионе+ файлов уже в разы замедляет процесс скана.
Программа Everything очень быстро ищет файлы, читая лог файловой системы. То есть прочитать лог быстрее, чем найти файлы в каталоге. Может вам стоит посмотреть в сторону работы с логом ($LogFile, $UsnJrnl of NTFS).
Ну, видимо это единственный вариант. Хотя это будет тот еще квест :)
Ну и тут может возникнуть другая проблема — размер MTF у меня 10,12 Гб…

P.S.: Я так и не нашел в .net других функций, которые бы не базировались бы в итоге на findfirst/findnext со всеми вытекающими из этого проблемами.
Ну это опять больше для риалтайма нужно… Да и тут C# уже не поможет и надо будет на C++ делать, со всеми вытекающими проблемами
Sign up to leave a comment.