我实际上正在开发科学的C ++模拟程序,它们读取数据,从中计算大量值,最后将结果存储在文件中。我想知道在程序开始时一次读取所有数据是否比在程序期间通过std::ifstream
继续访问文件更快。
我使用的数据不是很大(几MB),但我甚至不知道堆分配的“大”是什么......
我想这取决于数据等等(并且经过一些测试,实际上取决于它),但我想知道它取决于什么,以及是否有一种我们应该遵循的一般原则。
长话短说,问题是:保持文件打开并使用文件操纵器是否比潜在的大堆分配和使用字符串操纵器更快?
答案 0 :(得分:2)
看看mmap。此API允许您使用与RAM相同的分页机制将文件描述符映射到地址空间。这样,您既可以获得对数据的随机访问,又可以不必要地将不需要的数据复制到RAM中。
答案 1 :(得分:1)
在程序开头一次读取所有数据的速度是否比在程序中通过std :: ifstream访问文件更快?是的,可能是。请记住,工作内存快速且昂贵,而存储内存(硬盘驱动器)的存在恰好以便宜而代价慢。
堆分配的“大”是什么?操作系统会试图欺骗您的流程,让所有现有的工作内存都是免费的。实际上并非如此,如果某些进程请求太多内存,操作系统将为另一种类型“交换”一种类型的内存。但原则上,如果堆分配与工作内存的总大小相当,则应该认为堆分配很大。
保持文件打开并使用文件操作器是否比可能的大堆分配和使用字符串操纵器更快?不,它不是更快,但它还有另一个优点:它具有内存效率。如果您只将所需的数据放入内存以便使用它们,那么您将为机器中的所有其他进程(例如,可能是程序的其他线程)保存内存。这是一个非常有趣的属性,以便拥有可扩展的软件。
答案 2 :(得分:0)
(预计这将被关闭,因为这是一个“基于意见”的问题。)
我的想法:
答案 3 :(得分:0)
从大块文件中读取数据要比许多小尺寸的读取请求快得多。例如,1读取10MB比10读取1MB快。
当我优化文件I / O时,我将数据读入uint8_t
缓冲区,然后解析缓冲区。使用此方法的一个问题是读取文本文件。文本编码数据有可能跨越缓冲区边界。例如,每个文本行有4个数字,缓冲区中只有2个数字(或者只有2个数字位于缓冲区中)。您必须编写代码来处理这些情况。
如果您将程序视为管道,您可以进一步优化。您可以实现线程:读取线程,处理线程和写入(输出)线程。读取线程读入缓冲区。当有足够的数据进行处理时,读取线程会唤醒处理线程。处理线程处理读取的数据,当有一些输出时,它将它存储到共享缓冲区并唤醒输出线程。因此,对于管道模型,数据通过读取线程进入管道。在管道中的某个点处,处理线程处理数据。写入线程从处理线程获取数据并将其输出(退出管道)。
此外,组织数据以使其适合处理器缓存行也将加快您的程序。