Jak, z ... faktem, który sam nazywa printf, jest to możliwe? Czy jest coś, czego mi brakuje?
Tak, jest coś, czego brakuje. printf
niekoniecznie wywołuje write
za każdym razem. Raczej printf
buforuje swoje wyjście. Oznacza to, że często przechowuje wynik w buforze pamięci, wywołując tylko write
, gdy bufor jest pełny lub w innych warunkach.
write
to dość kosztowna rozmowa, znacznie droższa niż kopiowanie danych do bufora printf
, więc zmniejszenie liczby połączeń write
zapewnia wygraną netto.
Jeśli Twój odnośnik jest skierowany do urządzenia końcowego, wtedy printf
dzwoni write
za każdym razem, gdy widzi \n
- w twoim przypadku, za każdym razem, gdy jest wywoływane. Jeśli Twój odnośnik jest skierowany do pliku (lub do /dev/null
), wówczas wywołania printf
będą pisane tylko wtedy, gdy wewnętrzny bufor jest pełny.
Załóżmy, że przekierowujesz dane wyjściowe, a wewnętrzny bufor printf
ma rozmiar 4 KB, wtedy pierwsza pętla wywoła write
3000000/(4096/12) == 8780 razy. Twoja druga pętla wywołuje jednak write
3000000 razy.
Poza efektem mniejszej liczby połączeń z numerem write
, jest to rozmiar z połączeń z write
. Ilość pamięci na dysku twardym to sektor - często 512 bajtów. Zapisanie mniejszej ilości danych niż sektor może wymagać odczytania oryginalnych danych w sektorze, zmodyfikowania go i zapisania wyniku z powrotem. Wywoływanie write
z pełnym sektorem może jednak przebiegać szybciej, ponieważ nie trzeba czytać oryginalnych danych. printf
Rozmiar bufora jest wybrany jako wielokrotność typowego rozmiaru sektora. W ten sposób system może najskuteczniej zapisać dane na dysku.
Oczekuję, że twoja pierwsza pętla przejdzie znacznie szybciej niż druga.
zależy od Twojego systemu – JMBise
printf wykonuje buforowanie. –
Naprawdę? Obliczasz długość łańcucha za każdym razem, a następnie mierzysz to jako część taktów? –