我正在做一些非常关心效率的事情。文件数以千计,每个文件最大300M。每个文件至少包含 50 万个项目。我的工作是尽可能快地处理每个项目。物理内存大小不是问题。所以。我会从将整个文件复制到内存中并从内存中获取每个项目而不是从磁盘中获取每个项目中受益吗?还有其他方法可以节省 IO 过程的时间吗?谢谢!
2 回答
您可以使用mmap(2)、madvise(2)、posix_fadvise(2)和readahead(2)系统调用(请注意,这readahead
是 Linux 特定的且阻塞的,您可能需要提前调用它,或者在单独的线程中调用它)。
您可能不太在意:只需提前读取每个 200Mb 文件,在处理之前几秒钟,可能就足够了。内核文件系统和磁盘缓存做了很多工作;有很多 RAM 数据已经在内存中。
而且你没有告诉我们你的程序是否是一个单一的长期进程,或者你是否通过一些重复的脚本来驱动它,在每个大文件上调用相同的程序。
系统配置和硬件确实很重要。mke2fs
您可以(有时)用大块(例如 16Kb 或 64Kb)配置文件系统。如果你买得起,SSD磁盘会带来很多。
您还可以设计您的应用程序以仔细使用一些巧妙设置的数据库。
对于初学者:
std::vector<char> input;
std::ifstream file("filename.txt")'
// maybe find file size and do a reserve on input
std::copy(std::istream_iterator<char>(file), std::istream_iterator<char>()
std::back_inserter(input));
如果这实际上对您来说不够快,内存映射文件通常会减少很多 IO 开销。
Boost.Iostream库提供具有现代界面的可移植内存映射文件,而且速度非常快。
无论如何:首先尝试简单的解决方案,构建您的程序以将文件 IO 过程与解析器和实际处理分开,然后优化实际上昂贵的部分。这样的程序结构也将允许轻松实现生产者/消费者并行性。
一个重要的部分也是你items
是什么。它们可以直接映射到 astruct
还是必须进行处理。如果是这样,实际解析有多复杂?