Вот простой тестовый пример, демонстрирующий очевидную медленность при доступе к файлам для записи в Windows / NTFS по сравнению с Linux / ext4:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <sys/time.h>
#include <string.h>
static double time_ms(void)
{
struct timeval tv;
struct timezone tz;
gettimeofday(&tv, &tz);
int time_now = (int)(tv.tv_sec * 1000 + tv.tv_usec / 1000);
return (double)time_now / 1000.0;
}
int main(int argc, char *argv[])
{
argc--;
argv++;
int line = 0;
double start = time_ms();
if (argc < 2)
return 0;
int step = atoi(argv[1]);
int do_sync = (argc > 2 && strcmp(argv[2], "sync") == 0);
while(1)
{
FILE *f = fopen("test", argv[0]);
if (step == 0)
line++;
else for (int j = 0; j < step; j++)
{
fprintf(f, "Adding line %08d at %ld\n", line, time(0));
line++;
}
fclose(f);
#ifdef SYNC
if (do_sync)
sync();
#endif
if (line % 1000 == 0)
{
double dt = time_ms() - start;
if (dt)
printf("Written %s %d lines at %.2f lines/s\n", argv[0], line, line / dt);
}
}
}
linux компиляция:
gcc -o append append.c
и
gcc -o append append.c -DSYNC
(кросс) скомпилировано на linux с помощью mxe:
x86_64-w64-mingw32.static-gcc -o append.exe append.c
Это открывает файл, записывает несколько строк и закрывает его. 'режим' и 'количество строк' могут быть указаны в командной строке, а также для linux можно указать 'syn c' для выполнения syn c ()
запустите так:
./append a 10
./append a 100 sync
./append w 1
результаты:
lines/sec windows linux nosync
append 0 200 6,000 500,000
append 1 150 300 240,000
append 10 1500 3,000 1,800,000
append 100 15000 30,000 5,000,000
write 0 230 300 240,000
write 1 180 280 30,000
write 10 1700 2800 300,000
write 100 17000 28000 2,000,000
Эти тесты были запущены на другом оборудовании для Linux и Windows (10), но первые два столбца я считаю сопоставимы - это показывает, что Linux + syn c () работает примерно с той же скоростью, что и windows. но при "нормальной" работе без syn c, Linux явно работает во много тысяч раз быстрее, так как запись файлов передается в cache / os / ext4 /...
Я понимаю что фактические конечные записанные строки / с не такие, как показано, но в реальном приложении эти «медленные» записи блокируют и вызывают заметное заикание в пользовательском интерфейсе.
Я экспериментировал с
- с использованием open () / write () вместо потоковой передачи fopen ()
- fopen r + и fseek () вместо «a»
- «родной» FileCreate и FileWrite
- при компиляции с VS
, и результаты различаются, но все равно ничего похожего на Linux nosyn c результатов.
Текущее «решение» Я должен записать файлы в отдельном потоке, что вызывает свои собственные проблемы!
Могу я что-нибудь сделать, чтобы ускорить это?
Спасибо,