Какой самый быстрый способ чтения огромных файлов в Delphi? - PullRequest
3 голосов
/ 06 января 2011

Моя программа должна читать куски из огромного двоичного файла с произвольным доступом.У меня есть список смещений и длин, которые могут иметь несколько тысяч записей.Пользователь выбирает запись, и программа ищет смещение и считывает длину байтов.

Программа внутренне использует TMemoryStream для хранения и обработки фрагментов, считанных из файла.Чтение данных выполняется с помощью TFileStream следующим образом:

FileStream.Position := Offset;
MemoryStream.CopyFrom(FileStream, Size);

Это прекрасно работает, но, к сожалению, становится все медленнее по мере увеличения файлов.Размер файла начинается с нескольких мегабайт, но часто достигает нескольких десятков гигабайт.Размер читаемых фрагментов составляет около 100 кбайт.

Содержимое файла читается только моей программой.Это единственная программа, обращающаяся к файлу в то время.Кроме того, файлы хранятся локально, так что это не проблема сети.

Я использую Delphi 2007 для Windows XP.

Что я могу сделать, чтобы ускорить доступ к этому файлу?

edit:

  • Доступ к файлам для больших файлов медленный, независимо от того, какая часть файла читается.
  • Программа обычно не читает файл последовательно,Порядок чанков определяется пользователем и не может быть предсказан.
  • Всегда читать чанк из большого файла всегда медленнее, чем читать такой же большой чанк из небольшого файла.
  • IЯ говорю о производительности чтения фрагмента из файла, а не об общем времени, которое требуется для обработки всего файла.Последнее, очевидно, заняло бы больше времени для больших файлов, но здесь проблема не в этом.

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

Извините забыть небрежным в определении узкого места.

Ответы [ 3 ]

3 голосов
/ 06 января 2011

Если вы откроете раздел справки для CreateFile () функции WinAPI, вы найдете там интересные флаги, такие как FILE_FLAG_NO_BUFFERING и FILE_FLAG_RANDOM_ACCESS. Вы можете играть с ними, чтобы получить некоторую производительность.

Затем копирование данных файла, даже размером 100 КБ, является дополнительным шагом, который замедляет операции. Рекомендуется использовать функции CreateFileMapping и MapViewOfFile, чтобы получить готовый указатель на данные. Таким образом, вы избегаете копирования и, возможно, получаете определенные преимущества в производительности (но вам нужно тщательно измерять скорость).

0 голосов
/ 08 января 2011

Запас TMemoryStream в Delphi медленный из-за того, как он выделяет память. У компании NexusDB есть TnxMemoryStream, который намного эффективнее. Там могут быть некоторые бесплатные, которые работают лучше.

Стандартный Delphi TFileStream также не самый эффективный компонент. Путь в историю Джулиан Бакнолл опубликовал компонент с именем BufferedFileStream в журнале или где-то еще, который очень эффективно работал с файловыми потоками.

Удачи.

0 голосов
/ 06 января 2011

Может быть, вы можете использовать этот подход:

Сортировка записей по максимальному расположению файлов, а затем по следующему:

  1. Возьмите записи, которым требуется только первый X МБ файла (до определенного расположения файла)
  2. Чтение X МБ из файла в буфер (TMemorystream
  3. Теперь прочитайте записи из буфера (возможно, многопоточные)
  4. Повторите это для всех записей.

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

Может быть, вы сможете набрать скорость, если вы просто выберете исходный подход, но отсортируете записи по позиции.

...