gpt4 book ai didi

c - 写入超过 2.5GB 后,fputs 的性能下降。为什么?

转载 作者:可可西里 更新时间:2023-11-01 12:47:33 25 4
gpt4 key购买 nike

目前我正在开发一个读取大文件并对它们进行排序的小程序。经过一些基准测试后,我偶然发现了一个奇怪的性能问题。当输入文件变大时,输出文件的写入比实际排序花费的时间更长。所以我深入研究了代码,最终意识到 fputs 函数可能是问题所在。所以我写了这个小基准测试程序。

#include "stdio.h"
#include "ctime"

int main()
{
int i;
const int linecount = 50000000;
//Test Line with 184 byte
const char* dummyline = "THIS IS A LONG TEST LINE JUST TO SHOW THAT THE WRITER IS GUILTY OF GETTING SLOW AFTER A CERTAIN AMOUNT OF DATA THAT HAS BEEN WRITTEN. hkgjhkdsfjhgk jhksjdhfkjh skdjfhk jshdkfjhksjdhf\r\n";
clock_t start = clock();
clock_t last = start;

FILE* fp1 = fopen("D:\\largeTestFile.txt", "w");
for(i=0; i<linecount; i++){
fputs(dummyline, fp1);
if(i%100000==0){
printf("%i Lines written.\r", i);
if(i%1000000 == 0){
clock_t ms = clock()-last;
printf("Writting of %i Lines took %i ms\n", i, ms);
last = clock();
}
}
}
printf("%i Lines written.\n", i);
fclose(fp1);
clock_t ms = clock()-start;
printf("Writting of %i Lines took %i ms\n", i, ms);

}

当您执行该程序时,您可以看到大约 14 到 15 行 mio 行(大约 2.5GB 数据)后性能明显下降。写作时间大约是以前的 3 倍。 2GB 的阈值表明存在 64 位问题,但我还没有在网络上找到任何相关信息。我还测试了二进制模式和字符模式(例如“wb”和“w”)之间是否存在差异,但没有。我还尝试通过寻找预期的结尾并写入零字节来预分配文件大小(以避免文件碎片),但这也几乎没有效果。

我正在运行 Windows 7 64 位计算机,但我也在 Windows Server 2008 64 位 R1 计算机上对其进行了测试。目前,我正在一个 NTFS 文件系统上进行测试,该文件系统有超过 200GB 的可用空间。我的系统有 16GB 的 RAM,所以这也不成问题。测试程序只使用了大约 700KB。我之前怀疑的页面错误也非常低(整个运行时大约有 400 个页面错误)。

我知道对于如此大的数据,fwrite() 函数可以更好地完成任务,但目前我很想知道是否有其他解决方法以及为什么会发生这种情况。任何帮助将不胜感激。

最佳答案

这一切的主要原因是 Windows 磁盘缓存。然后你的程序会为它吃掉所有 RAM,然后交换开始,因此速度变慢。要对抗这些,您需要:

1) 使用 c 标志以提交模式打开文件:

FILE* fp1 = fopen("D:\\largeTestFile.txt", "wc");

2) 使用flush 函数定期将缓冲区写入磁盘:

if(i%1000000 == 0)
{
// write content to disk
fflush(fp1);

clock_t ms = clock()-last;
printf("Writting of %i Lines took %i ms\n", i, ms);
last = clock();
}

这样您将使用合理数量的磁盘缓存。速度基本上会受到硬盘驱动器速度的限制。

关于c - 写入超过 2.5GB 后,fputs 的性能下降。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8076757/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com