В настоящее время я работаю над небольшой программой, которая читает большие файлы и сортирует их.После некоторого бенчмаркинга я наткнулся на странную проблему производительности.Когда входной файл стал большим, запись выходного файла заняла больше времени, чем фактическая сортировка.Поэтому я углубился в код и наконец понял, что проблема может быть в функции 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 млн. Строк, что составляет около 2,5 ГБ данных.Запись занимает в 3 раза больше времени, чем раньше.Порог в 2 ГБ указывает на 64-битную проблему, но я не нашел ничего об этом в сети.Я также проверил, есть ли разница между двоичным и символьным режимом (например, "wb" и "w"), но нет.Я также попытался предварительно выделить размер файла (чтобы избежать фрагментации файла), выполнив поиск ожидаемого конца и записав нулевой размер, но это также мало что дало.
Я использую 64-битную машину Windows 7, но яЯ также проверил его на 64-битной машине с Windows Server 2008 R1.В настоящее время я тестирую файловую систему NTFS с более чем 200 ГБ свободного места.Моя система имеет 16 ГБ оперативной памяти, так что это тоже не должно быть проблемой.Тестовая программа использует только около 700 КБ.Ошибки страниц, о которых я подозревал ранее, также очень малы (~ 400 ошибок страниц за все время выполнения).
Я знаю, что для таких больших данных функция fwrite () подойдет для этой задачи лучше, но прив тот момент, когда меня интересует, есть ли другой обходной путь и почему это происходит.Любая помощь будет принята с благодарностью.