Ответ 1
Как, с... тем фактом, что printf сам вызывает запись, возможно ли это? Есть что-то, что мне не хватает?
Да, есть что-то, чего вам не хватает. printf
не обязательно вызывает write
каждый раз. Скорее, printf
буферизует свой вывод. То есть он часто сохраняет свой результат в буфере памяти, вызывая только write
, когда буфер заполнен, или в некоторых других условиях.
write
- довольно дорогостоящий вызов, намного более дорогостоящий, чем копирование данных в буфер printf
, поэтому уменьшение количества вызовов write
обеспечивает чистый выигрыш в производительности.
Если ваш stdout направлен на терминальное устройство, то printf
вызывает write
каждый раз, когда видит \n
- в вашем случае, каждый раз, когда он вызывается. Если ваш stdout направлен на файл (или на /dev/null
), то printf
вызывает запись только при заполнении внутреннего буфера.
Предположим, что вы перенаправляете свой вывод и что внутренний буфер printf
составляет 4 Кбайта, тогда первый цикл вызывает write
3000000/(4096/12) == 8780 раз. Однако ваш второй цикл вызывает write
3000000 раз.
Помимо меньшего количества вызовов на write
, это размер вызовов write
. Квантом хранения на жестком диске является сектор - часто 512 байт. Чтобы написать меньший объем данных, чем сектор, может потребоваться считывание исходных данных в секторе, его изменение и запись результата. Однако вызов write
с полным сектором может ускориться, поскольку вам не нужно читать исходные данные. printf
размер буфера выбран как кратный типичному размеру сектора. Таким образом, система может наиболее эффективно записывать данные на диск.
Я ожидаю, что ваш первый цикл пройдет намного быстрее, чем второй.