什么会花费更少的时间:读取多个文件或将内容合并到一个大文件中?
What will take less time: reading multiple files or merging contents into a large file?
我需要打开和操作存在于多个文件中的数据,这些文件位于多个文件夹中。我们说的是大约 500k 个文件,其中包含大约 5Gb 的数字数据。
我已经处理过这些数据,但是 运行 半简单算法需要大约一个小时。
我想知道更改文件地址的过程是否是最耗时的操作......(因为我必须在连接我想要访问的 folders/files 数字的地方做循环)。
我正在将所有原始数据合并到一个文件(带有文件 ID)中,希望花更少的时间来浏览所有原始数据...
我这个假设正确吗?这将花费我很多时间。
我正在用 C++ 做这个。
感谢您的任何输入
@Thomas:感谢您的建议。我正在添加多个缓冲区,它已经显示出有希望的迹象。我肯定会为每个任务启动线程。
我将尝试使我的阵列大小约为 1 Mb,看看它是否真的加快了速度。所有的缓冲区都是全局变量,所以应该没问题...
我认为您的问题没有硬性快速的答案。如果您尝试访问整个销售的数据(即您没有挑选和选择 data/files 的特定块),我认为如果您将所有数据放在一个位置会更快。
如果您每次 运行 只需要特定信息,而文件只允许您访问该信息,那么我会坚持使用您当前的结构。
要考虑的另一件事是您 运行 执行此过程的频率是多少?您 运行 正在查看相同的信息吗?如果您正在进行一次性分析,我建议您将其保留,即使这确实需要更多时间。如果这是您要定期 运行 的例行程序,并且您希望再次对所有信息执行此操作,则可能值得将您的数据分组到一个大集合中
通常,读取文件是性能的主要瓶颈之一。那么,让我们从这里开始吧。
优化文件读取
优化输入文件读取的最佳方法是减少输入请求的数量并扩大每个请求的数据量。因此,与其一次读取一个值,不如使用一条读取语句读取一组值。
块阅读
我建议将大块 (1Mb) 的数据读取到内存中,然后从缓冲区中提取数据。您需要考虑数据跨越缓冲区末尾到新缓冲区的情况。
内存映射文件
一些 OSes 具有将文件视为内存中字节数组的功能。 OS 为您处理将数据加载到内存中。这不是标准的 C++,并且取决于 OS。
多线程,一个阅读
另一种解决方案是使用多个线程,至少两个。其中一个线程的任务是将数据读入缓冲区并通知另一个线程数据已准备就绪。 OS 可以将读取线程委托给另一个核心,允许另一个核心执行计算。
双缓冲和多缓冲
在多线程上扩展,使用多个数据缓冲区。 "reading" 线程将读入一个缓冲区,而另一个线程从另一个缓冲区中提取数据。这个想法是使用尽可能多的缓冲来减少计算线程的等待量。
正在更改数据格式
固定长度记录比可变长度记录读取速度更快。因此,如果数据只是数字,请使用固定宽度的字段。
如果多次读取数据,请考虑一次读取文件并写入二进制(原始、非文本)格式的新文件。从该文件中读取第 2 次和更多次迭代,这消除了从文本格式转换为内部格式的需要。
每个文件访问都有开销。系统在能够访问它之前需要查找它的物理位置。
如果您避免该查找,则可以减少一些开销。
如果您可以按照需要的顺序将数据放入文件中,您肯定会看到更显着的加速,尤其是在使用传统硬盘驱动器的情况下。如果您使用的是 SSD 并且有大量 RAM 用于缓存,则改进不会那么显着。
如果您可以访问大块数据,您将看到好处。如果您的计算需要随机访问您的数据,您最好增加磁盘缓存的 RAM 或购买 SSD。
我需要打开和操作存在于多个文件中的数据,这些文件位于多个文件夹中。我们说的是大约 500k 个文件,其中包含大约 5Gb 的数字数据。
我已经处理过这些数据,但是 运行 半简单算法需要大约一个小时。 我想知道更改文件地址的过程是否是最耗时的操作......(因为我必须在连接我想要访问的 folders/files 数字的地方做循环)。 我正在将所有原始数据合并到一个文件(带有文件 ID)中,希望花更少的时间来浏览所有原始数据...
我这个假设正确吗?这将花费我很多时间。 我正在用 C++ 做这个。 感谢您的任何输入
@Thomas:感谢您的建议。我正在添加多个缓冲区,它已经显示出有希望的迹象。我肯定会为每个任务启动线程。 我将尝试使我的阵列大小约为 1 Mb,看看它是否真的加快了速度。所有的缓冲区都是全局变量,所以应该没问题...
我认为您的问题没有硬性快速的答案。如果您尝试访问整个销售的数据(即您没有挑选和选择 data/files 的特定块),我认为如果您将所有数据放在一个位置会更快。
如果您每次 运行 只需要特定信息,而文件只允许您访问该信息,那么我会坚持使用您当前的结构。
要考虑的另一件事是您 运行 执行此过程的频率是多少?您 运行 正在查看相同的信息吗?如果您正在进行一次性分析,我建议您将其保留,即使这确实需要更多时间。如果这是您要定期 运行 的例行程序,并且您希望再次对所有信息执行此操作,则可能值得将您的数据分组到一个大集合中
通常,读取文件是性能的主要瓶颈之一。那么,让我们从这里开始吧。
优化文件读取
优化输入文件读取的最佳方法是减少输入请求的数量并扩大每个请求的数据量。因此,与其一次读取一个值,不如使用一条读取语句读取一组值。
块阅读
我建议将大块 (1Mb) 的数据读取到内存中,然后从缓冲区中提取数据。您需要考虑数据跨越缓冲区末尾到新缓冲区的情况。
内存映射文件
一些 OSes 具有将文件视为内存中字节数组的功能。 OS 为您处理将数据加载到内存中。这不是标准的 C++,并且取决于 OS。
多线程,一个阅读
另一种解决方案是使用多个线程,至少两个。其中一个线程的任务是将数据读入缓冲区并通知另一个线程数据已准备就绪。 OS 可以将读取线程委托给另一个核心,允许另一个核心执行计算。
双缓冲和多缓冲
在多线程上扩展,使用多个数据缓冲区。 "reading" 线程将读入一个缓冲区,而另一个线程从另一个缓冲区中提取数据。这个想法是使用尽可能多的缓冲来减少计算线程的等待量。
正在更改数据格式 固定长度记录比可变长度记录读取速度更快。因此,如果数据只是数字,请使用固定宽度的字段。
如果多次读取数据,请考虑一次读取文件并写入二进制(原始、非文本)格式的新文件。从该文件中读取第 2 次和更多次迭代,这消除了从文本格式转换为内部格式的需要。
每个文件访问都有开销。系统在能够访问它之前需要查找它的物理位置。 如果您避免该查找,则可以减少一些开销。 如果您可以按照需要的顺序将数据放入文件中,您肯定会看到更显着的加速,尤其是在使用传统硬盘驱动器的情况下。如果您使用的是 SSD 并且有大量 RAM 用于缓存,则改进不会那么显着。 如果您可以访问大块数据,您将看到好处。如果您的计算需要随机访问您的数据,您最好增加磁盘缓存的 RAM 或购买 SSD。