【发布时间】:2011-01-06 13:19:25
【问题描述】:
我的程序需要从一个随机访问的巨大二进制文件中读取块。我有一个可能有几千个条目的偏移量和长度列表。用户选择一个条目,程序会寻找偏移量并读取长度字节。
程序内部使用 TMemoryStream 来存储和处理从文件中读取的块。读取数据是通过这样的 TFileStream 完成的:
FileStream.Position := Offset;
MemoryStream.CopyFrom(FileStream, Size);
这工作正常,但不幸的是,随着文件变大,它变得越来越慢。文件大小从几兆字节开始,但经常达到几十千兆字节。读取的块大小约为 100 KB。
文件的内容只能被我的程序读取。它是当时唯一访问该文件的程序。此外,文件存储在本地,因此这不是网络问题。
我在 Windows XP 机器上使用 Delphi 2007。
我可以做些什么来加快这个文件的访问速度?
编辑:
- 无论读取文件的哪个部分,大文件的文件访问都很慢。
- 程序通常不会顺序读取文件。块的顺序是用户驱动的,无法预测。
- 从大文件中读取块总是比从小文件中读取同样大的块要慢。
- 我说的是从文件中读取块的性能,而不是处理整个文件所需的总时间。对于较大的文件,后者显然需要更长的时间,但这不是问题所在。
我需要向大家道歉:在我按照建议使用内存映射文件实现文件访问之后,结果证明它并没有太大的区别。但是在我添加了更多的计时代码之后,结果也证明不是文件访问会减慢程序的速度。无论文件大小如何,文件访问实际上都需要几乎恒定的时间。用户界面的某些部分(我尚未确定)似乎在处理大量数据时存在性能问题,并且不知何故,当我第一次对流程进行计时时,我没有看到差异。
我很抱歉在确定瓶颈时马虎。
【问题讨论】:
-
我没有看到任何明显的东西。这些流类只是系统文件 I/O 函数的包装器。您如何才能显着改进随机访问模式?
-
您是说单次查找/读取对用户来说明显变慢了吗?或者这些操作中的大“批次”速度较慢?如果数据来自磁盘,则无论文件大小如何,单个查找和读取操作都应该大致相同。对于 7200 rpm 的磁盘,这应该在 5 到 10 毫秒之间。
-
可能是内存碎片问题。您是否在操作之间释放 TMemoryStream?尝试在应用程序的整个生命周期内保持其活动状态,看看减速是否会消失。
-
@mark:这是从文件中读取块的单个操作,大文件比小文件慢得多。 (将此信息添加到问题中)
-
@Cosmin:它不会随着程序运行的时间变慢,但对于大文件来说启动很慢。
标签: delphi file-io delphi-2007 tfilestream