- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
目前我正在开发一个读取大文件并对它们进行排序的小程序。经过一些基准测试后,我偶然发现了一个奇怪的性能问题。当输入文件变大时,输出文件的写入比实际排序花费的时间更长。所以我深入研究了代码,最终意识到 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/
以下编程在“fputs”的第一个实例处崩溃,尝试将“fname”打印到文件 Member_inf。我还尝试打印常量字符串“abcdefg”,但仍然失败。到底做错了什么?看来是文件的初始化。如果可能的话
我的输入文件包含以下格式的产品集合: name price symbol 示例文件是: Ball 6.24 u 我想读取文件,将文本解析为struct,并使用相同的元素重写文件,但不包含带有符号u的元
总的来说,我对 C 语言和内存分配还很陌生。基本上我想做的是复制未知大小的输入文件的内容并使用递归反转其内容。我觉得我已经非常接近了,但是当我尝试放入我认为是文件反转内容的内容时,我不断遇到段错误(我
fseek(ofile, 13, SEEK_SET); fputs("\t", ofile); do { ch = getc(ofile); printf("%c", ch);
当运行下面的代码时,我没有得到任何输出,但我不知道为什么。 # include int main() { fputs("hello", stdout); while (1);
我试图在文件中写入数组的全部内容。这是我的代码: fichier = fopen(patch, "w+"); if (fichier != NULL) { if(methode=
#include int main() { FILE *fp; char str[60]; char data[50]; char * pch; /* opening
我在完成下面的作业时遇到了问题。每当我尝试将 fputs 参数合并到一行中时,错误都会显示 fputs 中的参数过多。 我想做的是在每个子文件中创建一个输出,其中包括时间以及一行中的文本,但下面的代码
我有以下代码: #include #include #include using namespace std; int main(){ size_t size; char *li
int main(int argc, char *argv[]) { FILE *datafile, *outputfile; char c, *line, *line1, *line
在这个程序中,我的 edit() 函数无法正常工作。当我尝试写一些东西时,它只会删除整个内容,而在 appendText() 中只有一个单词被附加?有没有办法将整个字符串写入文件? #include
我目前正在尝试用 C 语言创建一个数据库,使用 .txt 文档作为存储所有数据的地方。但是我无法让 fputs() 换行,所以我的程序在此 .txt 文档中写入的所有内容都只在一行上。 int
我有以下简单代码: #include int main(){ char buffer[20] = "abc"; FILE *pFile; pFile
我终于让自己去看了一些 Linux 代码。我现在正在查看 ls.c。 在底部的函数 usage() 中,我发现了很多这样的语句: fputs (_("\ List information about
不可能执行类似 fputs(4, fptOut); 的操作,因为 fputs 不喜欢整数。我该如何解决这个问题? 执行 fputs("4", fptOut); 不是一个选项,因为我正在使用计数器值。
或等效地, 为什么 puts() 会追加一个尾随换行符? 当输出字符串时,可能会用到两个类似的函数:fputs() 和puts()。 puts() 在输出时自动在末尾添加一个新行,但 fputs()
我在 Windows 上遇到文件写入失败的问题。我将它简化为这个例子: FILE* f = fopen("test.out", "r+b"); fseek(f, -1, SEEK_END); // o
为什么 fputs() 或 fprintf() 没有写入 %s 的 file.txt ?我尝试了这两个函数,但它们似乎没有写入文件。但是,当对 %d 使用相同的函数时,它目前确实有效。至于预期输出与当
为什么 fputs() 或 fprintf() 没有写入 %s 的 file.txt ?我尝试了这两个函数,但它们似乎没有写入文件。但是,当对 %d 使用相同的函数时,它目前确实有效。至于预期输出与当
假设test.txt是这样的: aaaaa aaaaa aaaaa 测试代码是这样的: #include #include #include int main() { FILE *f = f
我是一名优秀的程序员,十分优秀!