我正在使用C中的 fread 读取1 GB文件。我正在使用以下循环以1MB块读取文件:
FILE *fp;
fp = fopen(filename, "rb");
unsigned char* buf;
buf = malloc(CHUNK_SIZE);
for(i = 0; i < NUMBER_OF_CHUNKS; ++i)
{
fread(buf, CHUNK_SIZE, 1, fp);
//Do something with contents of buffer
}
fclose(fp);
以这种方式读取文件大约需要2秒钟。
但是,我决定我想为整个文件的内容分配一个大缓冲区,并在每次迭代时在 fread 函数内“移动缓冲区指针”,如下所示:
FILE *fp;
fp = fopen(filename, "rb");
unsigned char* buf;
buf = malloc(CHUNK_SIZE * NUMBER_OF_CHUNKS);
for(i = 0; i < NUMBER_OF_CHUNKS; ++i)
{
fread(&buf[i*CHUNK_SIZE], CHUNK_SIZE, 1, fp);
}
fclose(fp);
这显着减慢了读数,现在大约需要40秒。
我的问题是:
该文件由一行字母数字字符组成。
我想以第二种方式阅读它,以便我可以让其他线程访问已经读取的缓冲区中的块,而读取线程继续填充缓冲区的其余部分。
谢谢!
答案 0 :(得分:1)
您的计算机可能内存不足。一个千兆字节需要分配很多内存。你的操作系统我必须将一些数据交换到磁盘,这将导致一个数量级的减速。
您可以考虑单独分配每个块,并在完成后释放它们。这样,程序的总内存使用量受工作集的限制,而不是整个文件。
答案 1 :(得分:0)
当内存不足并且操作系统在交换分区中来回切换时,您不仅会导致大约3倍的磁盘流量。此外,对于机械/旋转硬盘[是的,那些仍然非常普遍],头部需要来回寻找交换空间和正在阅读的文件 - 即使文件没有碎片。这很可能会造成10-15倍的额外速度惩罚。
可能的解决方法是使用mmap
将内存映射为连续内存,允许操作系统决定最佳交换策略。