将文件读入内存的最快技术?

Posted

技术标签:

【中文标题】将文件读入内存的最快技术?【英文标题】:fastest technique to read a file into memory? 【发布时间】:2012-06-05 21:18:34 【问题描述】:

是否有一种普遍接受的最快技术用于在 c++ 中将文件读入内存?

我只会读取文件。

我已经看到 boost 有一个实现,我在这里也看到了其他几个实现,但我想知道什么被认为是最快的?

提前谢谢你

以防万一,我正在考虑最大为 1GB 的文件,这适用于 Windows。

【问题讨论】:

最快的方法是读取大小与磁盘缓冲区对齐的连续块(​​例如 8MB,如果您的磁盘有 8MB 缓冲区)。 真的很重要吗? 你确定?您是否分析了您的代码并证明读取文件需要多长时间是一个问题?如果是这样,您可能需要使用特定于操作系统的工具来获得最佳性能。 如果你能说出你想对文件做什么,这会有所帮助。 What is the best way to slurp a file into a std::string in c++? 的可能重复项 【参考方案1】:

使用memory-mapped files,可能使用boost wrapper 以实现可移植性。

如果要读取大于虚拟地址空间的空闲连续部分的文件,可以随意移动文件的映射部分。

【讨论】:

我必须为那个 boost 库预编译头文件还是为你完成?我记得有些 boost 库需要单独编译吗? @Porcupine:文档说“要管理映射文件,您只需要包含以下标头:#include <boost/interprocess/file_mapping.hpp>”,所以我认为它是一个仅限标头的库。 好的,它绝对是一个只有头文件的库,正如 here 所指定的那样:“不需要编译 Boost.Interprocess,因为它是一个只有头文件的库。只需在你的 Boost 头目录中包含编译器包含路径。”【参考方案2】:

请考虑使用 Memory-Mapped Files 来处理您的情况,因为文件最大可达到 1 GB。

Memory-mapped files and how they work

在这里你可以从 win32 API 开始:

MapViewOfFile

MSDN 页面上还有其他几个有用的 API。

【讨论】:

这只是 istream 吗? istream 是我想要的吗? @Porcupine:不是istream。通过链接了解它是什么。如果我用几句话来解释,那么它对你没有任何好处,而且可能是不准确的。【参考方案3】:

如果内存映射文件不足以满足您的应用程序,并且文件 I/O 是您的瓶颈,使用 I/O completion port 处理文件上的异步 I/O 将是您在 Windows 上获得的最快速度。

I/O 完成端口为 在多处理器上处理多个异步 I/O 请求 系统。当一个进程创建一个 I/O 完成端口时,系统 为唯一目的是的请求创建一个关联的队列对象 为这些请求提供服务。处理许多并发的进程 异步 I/O 请求可以通过以下方式更快、更有效地做到这一点 结合预分配线程使用 I/O 完成端口 池而不是在收到 I/O 请求时创建线程。

【讨论】:

但是读取单个文件在我看来并不像 »许多并发异步 I/O 请求«。 同意,如果这是针对单个低于 1GB 的文件,那就太过分了。我不想根据 q 的模棱两可的文本来假设 OP 想要什么。【参考方案4】:

一般来说,mmap 是。但是在 Windows 中,他们发明了自己的方法,请参阅"File Mapping"。 Boost 有 Memory-Mapped Files 库,可以将两种方式都封装在可移植的代码堆中。

此外,如果您想提高速度,就必须针对您的用例进行优化。仅仅将文件内容映射到内存是不够的。例如,您确实可能不需要内存映射文件,最好使用异步文件 I/O。很多问题都有很多解决方案。

【讨论】:

以上是关于将文件读入内存的最快技术?的主要内容,如果未能解决你的问题,请参考以下文章

堆叠 CSV 文件的最快方法

c++ 中将标准输入内容读入字符串或向量的最快方法

处理大文件的最快方法?

读取 100,000 个 .dat.gz 文件的最快方法

多线程应用程序中最快的文件读取

读取大型二进制文件每 30 个字节的最快方法?