快速阅读文件
Reading through files quickly
本文关键字:文件 更新时间:2023-10-16
我的问题是:如何使用C++或C程序快速读取超过50 MB 的文件(即大约一秒钟内)...
我感兴趣的是文件,其中包含纯整数...
我已经排除了 ifstream,因为它对于这个目的来说太慢了(8-9 秒)。
目前,我正在使用 fscanf,但它仍然非常非常慢(4 秒)....
我 100% 确定读取文件的方式是问题所在,并且我没有 I/O 限制。
你能建议任何替代方案吗?
编辑
文件格式:
1 2 41 2 1 5 1 2 ... (integers)
尝试使用内存映射文件。尝试谷歌搜索
CreateFileMapping
MapViewOfFile
为了更快地读取数据,您必须减少读取量并增加读取数据量。
假设最坏的情况,硬盘驱动器必须为每个读取命令初始化:
- 拼盘必须跟上速度(需要时间)。
- 操作系统读取目录结构。
- 操作系统会在目录结构中搜索您的文件。
- 操作系统告诉硬盘驱动器要读取哪个扇区或盘片和扇区从。
- 硬盘等待扇区启动,然后读取来自该部门开始的连续数据。
- 硬盘降速。
除了从该行业读取之外,其他所有内容都被视为开销。 无论读取一个字节还是读取 10k,都将应用开销。 效率是保持驱动器旋转,这意味着每个"读取"命令读取更多数据。
有许多方法可以优化这一点:
- 单个大型缓冲区 -- 将大量数据读入单个缓冲区,并且分析缓冲区。
- 双缓冲或多重缓冲 -- 使用多个缓冲器,以便一个线程可以解析一个缓冲区,而另一个线程将数据读取到另一个缓冲区。
- 内存映射文件 -- 操作系统像管理文件读取一样管理文件记忆。
程序之外的其他方法:
- 优化文件数据结构,使用固定记录大小。
- 减少文件中的片段数量 - 瞄准一个巨大的硬盘上的连续区域。
为什么这个文件包含什么很重要?使用这个非常快速和肮脏的标准 C 程序读取一个 54Mb 文件需要半秒钟:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
unsigned char *big_file = NULL;
size_t length;
int main(int argc, char **argv)
{
FILE *f;
clock_t start_time, end_time;
if (argc >= 2)
{
start_time = clock();
f = fopen (argv[1], "rb");
if (f)
{
fseek (f, 0, SEEK_END);
length = ftell(f);
fseek (f, 0, SEEK_SET);
big_file = (unsigned char *)malloc(length);
if (big_file)
{
if (fread (big_file, 1,length, f) == length)
printf ("successfully read %lu bytesn", (unsigned long)length);
free (big_file);
}
fclose (f);
}
end_time = clock() - start_time;
printf ("this took %f second(s)n", ((double)end_time)/CLOCKS_PER_SEC);
}
}
输出:
successfully read 54721618 bytes
this took 0.523000 second(s)
请注意:在同一文件上再次运行它会返回以下内容:
successfully read 54721618 bytes
this took 0.037000 second(s)
有了这个,你的问题可能需要改写:"好的,这样我就可以快速阅读,但我需要对这些数据做XXX"——如果"XXX"="很多",你可能会超过1秒时间分配内剩余的0.477秒。
相关文章:
- .cpp和.h文件中的模板专用化声明
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 文本文件中的单词链表
- CMake-按正确顺序将项目与C运行时对象文件链接
- 使用新行和不使用新行读取文件
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 挂起和取消挂起一个文件DLL
- 如何确定我已使用非编码文件到达 EOF?
- 命名空间中具有.h和.cpp文件的类
- 如何使用ndk-build.cmd构建Android.so文件
- 从包含m行的文件中提取n行,必要时(惰性地)重复该文件
- 读取文件并输入到矢量中
- 在C++中查找文件
- c++库的公共头文件中应该包含什么
- 用c++从输入文件中读取另一行
- Cppcheck生成xml转储文件
- 读取文件的最后一行并输入到链接列表时出错
- 无法编译 rtmidi 测试 cmidiin.cpp 文件, 非法指令
- 如何将内容数组写入文本文件?
- C++ Windows 驱动程序MSB3030无法复制该文件,因为它找不到