À peu près.
Lorsque vous redirigez la sortie standard du programme vers /dev/null
, tout appel au printf(3)
évaluera toujours tous les arguments, et le processus de formatage de chaîne aura toujours lieu avant d'appeler write(2)
, qui écrit la chaîne entièrement formatée dans la sortie standard du processus. C'est au niveau du noyau que les données ne sont pas écrites sur le disque, mais rejetées par le gestionnaire associé au périphérique spécial /dev/null
.
Donc, au mieux, vous ne contournerez pas ou n'éviterez pas la surcharge d'évaluation des arguments et de les transmettre à printf
, le travail de formatage de chaîne derrière printf
, et au moins un appel système pour réellement écrire les données, simplement en redirigeant stdout vers /dev/null
. Eh bien, c'est une vraie différence sous Linux. L'implémentation renvoie simplement le nombre d'octets que vous vouliez écrire (spécifié par le 3ème argument de votre appel à write(2)
) et ignore tout le reste (voir cette réponse). Selon la quantité de données que vous écrivez et la vitesse du périphérique cible (disque ou terminal), la différence de performances peut varier considérablement. Sur les systèmes embarqués, de manière générale, couper l'écriture disque en redirigeant vers /dev/null
peut économiser pas mal de ressources système pour une quantité non négligeable de données écrites.
Bien qu'en théorie, le programme puisse détecter /dev/null
et effectuer certaines optimisations dans les limites des normes auxquelles ils se conforment (ISO C et POSIX), sur la base d'une compréhension générale des implémentations courantes, ce qu'ils ne font pratiquement pas (c'est-à-dire que je ne connais aucun système Unix ou Linux le faisant).
La norme POSIX impose l'écriture sur la sortie standard pour tout appel à printf(3)
, il n'est donc pas conforme à la norme de supprimer l'appel à write(2)
en fonction des descripteurs de fichiers associés. Pour plus de détails sur les exigences POSIX, vous pouvez lire la réponse de Damon. Oh, et une note rapide :toutes les distributions Linux sont pratiquement conformes à POSIX, bien qu'elles ne soient pas certifiées être ainsi.
Sachez que si vous remplacez printf
complètement, certains effets secondaires peuvent mal tourner, par exemple printf("%d%n", a++, &b)
. Si vous avez vraiment besoin de supprimer la sortie en fonction de l'environnement d'exécution du programme, envisagez de définir un indicateur global et de conclure printf pour vérifier l'indicateur avant l'impression - cela ne ralentira pas le programme dans une mesure où la perte de performances est visible , car une seule vérification de condition est beaucoup plus rapide que d'appeler le printf
et faire tout le formatage des chaînes.
Le printf
la fonction va écrire à stdout
. Il n'est pas conforme d'optimiser pour /dev/null
Par conséquent, vous aurez la charge d'analyser la chaîne de format et d'évaluer tous les arguments nécessaires, et vous aurez au moins un appel système, en plus vous copierez un tampon dans l'espace d'adressage du noyau (ce qui, comparé au coût de l'appel système est négligeable ).
Cette réponse est basée sur la documentation spécifique de POSIX.
Interfaces système
dprintf, fprintf, printf, snprintf, sprintf - imprime la sortie formatéeLa fonction fprintf() doit placer la sortie sur le flux de sortie nommé. La fonction printf() doit placer la sortie sur le flux de sortie standard stdout. La fonction sprintf() doit placer la sortie suivie de l'octet nul, '\0', dans des octets consécutifs commençant à *s ; il est de la responsabilité de l'utilisateur de s'assurer que suffisamment d'espace est disponible.
Définitions de base
devoir
Pour une implémentation conforme à POSIX.1-2017, décrit une fonctionnalité ou un comportement obligatoire. Une application peut s'appuyer sur l'existence de la fonctionnalité ou du comportement.