目前我正在开发一个读取大文件并对其进行排序的小程序。在进行一些基准测试后,我遇到了一个奇怪的性能问题。当输入文件变得很大时,输出文件的写入时间比实际排序时间更长。因此,我深入研究了代码,并最终意识到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);
}
当您执行程序时,可以看到大约在1400万至1500万行左右(约为2.5GB的数据)后性能明显下降。写入所需时间是之前的3倍。2GB阈值表明存在64位问题,但我在网络上没有找到任何相关信息。我还测试了二进制和字符模式之间是否有区别(例如“wb”和“w”),但并没有发现差异。我还尝试通过将文件大小预分配(以避免文件碎片化),将指针定位于期望的结尾并写入一个零字节,但效果很小或没有效果。
我正在运行Windows 7 64位机器,但我也在Windows Server 2008 64位 R1机器上进行了测试。目前,在具有超过200GB可用空间的NTFS文件系统上进行测试。我的系统有16GB RAM,因此也不应该存在问题。测试程序仅使用约700KB。我先前怀疑的页面错误数量也非常低(整个运行时间中约400页错误)。
我知道对于如此大的数据,fwrite()函数可能更适合此任务,但目前我想知道是否有其他解决方法以及为什么会出现这种情况。任何帮助都将不胜感激。