Я пытаюсь написать некоторый код, который работает и над Linux и над Win32. Наиболее заметным различием, которое я нахожу между ними (в моем коде) является производительность fopen()
.
Следующий код занимает 5 секунд на моей Ubuntu, и тот же код занимает больше чем 100 секунд на Windows XP. Я хотел бы записать здесь, что человечность является VM, в то время как XP находится на реальной машине.
time_t start = time(NULL);
for(int i=0; i < 100000; ++i){
FILE *fp = fopen("a.txt", "a");
if (fp != NULL)
{
fprintf(fp, "Hello World");
fclose(fp);
}
}
time_t end = time(NULL);
printf("\n It took %d seconds \n", end-start);
Очевидно fopen()
причина этого различия. Я хочу знать, почему это - такая большая разница?
Очевидно, что fopen() является причиной этого разница
Нет, более вероятно, что это промывка файловой системы.
На одной системе при записи, или, что более вероятно, вызове fclose(), происходит блокировка до тех пор, пока байты физически не окажутся на диске (или, по крайней мере, пока диск не скажет, что они там есть) - на другой файловая система возвращается сразу, даже если байты все еще записываются
Используете ли вы сканер вирусов? Если да, сначала отключите его!
И некоторые вызовы API в Windows выполняются медленнее. НАПРИМЕР. ваш C: \ сначала будет переведен в / harddrive / something (просто пример).
Здесь используется гораздо больше, чем просто API.
Вы открываете файл в файловой системе.
Таким образом, тип используемой файловой системы будет влиять на время, а также на скорость аппаратного обеспечения устройств, реализующих файловую систему. Вы просто не учитываете слишком много факторов, чтобы точно сказать, что X является виновником низких скоростей.
Это не имеет значения. Это необычный сценарий использования функций ввода-вывода, поэтому их не нужно оптимизировать для этого случая. Возможно, в Windows используется синхронный flush (), а в Linux - асинхронный.
Я бы сделал следующее:
По всей вероятности, они не делают то же самое. Скорее всего, виновата файловая система. Либо машина win32 делает намного больше операций по очистке - возможно, потому что у нее меньше доступной оперативной памяти из-за других задач - либо машина Linux работает на оборудовании, которое имитирует очистку и вводит другой уровень кэширования - т.е. обманывает.
Какой уровень долговечности требуется в вашем приложении? Если файлы абсолютно не должны исчезать при отключении питания (например, почтовый сервер, принимающий почту), то вам следует использовать fsync(). fclose() не гарантирует этого
. Если вы используете Visual C ++, имейте в виду, что по умолчанию stdio теперь использует мьютексы для обеспечения безопасной многопоточности. Их можно отключить с помощью #define _CRT_DISABLE_PERFCRIT_LOCKS
. [РЕДАКТИРОВАТЬ 31/12/2013] Я не уверен, но думаю, что реализации Linux stdio обычно предполагают однопоточное поведение, поэтому не нужно накладывать эти накладные расходы на блокировку. Реализации Linux stdio аналогично подчиняются стандартам POSIX и C11, которые требуют безопасной многопоточности, обеспечивая безблокирующие версии функций, имена которых заканчиваются на _unlocked
, например fgetc_unlocked ()
.
Дополнительная информация здесь: http://msdn.microsoft.com/en-us/library/ms235505%28v=VS.80%29.aspx