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