Cukup banyak.
Saat Anda mengarahkan stdout program ke /dev/null
, panggilan apa pun ke printf(3)
akan tetap mengevaluasi semua argumen, dan proses pemformatan string akan tetap berlangsung sebelum memanggil write(2)
, yang menulis string yang diformat penuh ke keluaran standar dari proses. Pada level kernel data tidak ditulis ke disk, tetapi dibuang oleh handler yang terkait dengan perangkat khusus /dev/null
.
Jadi yang terbaik, Anda tidak akan melewati atau menghindari overhead mengevaluasi argumen dan meneruskannya ke printf
, tugas pemformatan string di belakang printf
, dan setidaknya satu panggilan sistem untuk benar-benar menulis data, cukup dengan mengalihkan stdout ke /dev/null
. Nah, itulah perbedaan sebenarnya di Linux. Implementasinya hanya mengembalikan jumlah byte yang ingin Anda tulis (ditentukan oleh argumen ke-3 panggilan Anda ke write(2)
) dan mengabaikan yang lainnya (lihat jawaban ini). Bergantung pada jumlah data yang Anda tulis, dan kecepatan perangkat target (disk atau terminal), perbedaan kinerja dapat sangat bervariasi. Pada sistem tersemat, secara umum, memotong penulisan disk dengan mengalihkan ke /dev/null
dapat menghemat cukup banyak sumber daya sistem untuk jumlah data tertulis yang tidak sepele.
Walaupun secara teori, program ini dapat mendeteksi /dev/null
dan melakukan beberapa pengoptimalan dalam batasan standar yang mereka patuhi (ISO C dan POSIX), berdasarkan pemahaman umum tentang implementasi umum, secara praktis mereka tidak melakukannya (yaitu saya tidak mengetahui adanya sistem Unix atau Linux yang melakukannya).
Mandat standar POSIX menulis ke output standar untuk setiap panggilan ke printf(3)
, jadi tidak memenuhi standar untuk menekan panggilan ke write(2)
tergantung pada deskriptor file terkait. Untuk detail lebih lanjut tentang persyaratan POSIX, Anda dapat membaca jawaban Damon. Oh, dan catatan singkat:Semua distro Linux praktis sesuai dengan POSIX, meskipun tidak bersertifikat menjadi begitu.
Ketahuilah bahwa jika Anda mengganti printf
sepenuhnya, beberapa efek samping mungkin salah, misalnya printf("%d%n", a++, &b)
. Jika Anda benar-benar perlu menekan output tergantung pada lingkungan eksekusi program, pertimbangkan untuk menyetel flag global dan selesaikan printf untuk memeriksa flag sebelum mencetak — ini tidak akan memperlambat program hingga kehilangan performa terlihat , karena pemeriksaan kondisi tunggal banyak lebih cepat daripada memanggil printf
dan melakukan semua pemformatan string.
printf
fungsi akan tulis ke stdout
. Tidak sesuai untuk mengoptimalkan /dev/null
.Oleh karena itu, Anda akan memiliki biaya parsing string format dan mengevaluasi argumen yang diperlukan, dan Anda akan memiliki setidaknya satu syscall, plus Anda akan menyalin buffer ke ruang alamat kernel (yang, dibandingkan dengan biaya syscall dapat diabaikan ).
Jawaban ini didasarkan pada dokumentasi khusus POSIX.
Antarmuka Sistem
dprintf, fprintf, printf, snprintf, sprintf - keluaran berformat cetakFungsi fprintf() akan menempatkan keluaran pada aliran keluaran bernama. Fungsi printf() akan menempatkan keluaran pada stdout aliran keluaran standar. Fungsi sprintf() akan menempatkan keluaran diikuti oleh byte nol, '\0', dalam byte berurutan mulai dari *s; itu adalah tanggung jawab pengguna untuk memastikan bahwa cukup ruang tersedia.
Definisi Dasar
sebaiknya
Untuk implementasi yang sesuai dengan POSIX.1-2017, jelaskan fitur atau perilaku yang wajib. Sebuah aplikasi dapat mengandalkan keberadaan fitur atau perilaku.