GNU/Linux >> Linux Esercitazione >  >> Linux

printf avrà comunque un costo anche se reindirizzo l'output a /dev/null?

Più o meno.

Quando reindirizzi lo stdout del programma a /dev/null , qualsiasi chiamata a printf(3) valuterà comunque tutti gli argomenti e il processo di formattazione della stringa avrà ancora luogo prima di chiamare write(2) , che scrive la stringa formattata completa nell'output standard del processo. È a livello di kernel che i dati non vengono scritti su disco, ma scartati dal gestore associato al dispositivo speciale /dev/null .

Quindi, nella migliore delle ipotesi, non aggirerai o eviterai il sovraccarico di valutare gli argomenti e passarli a printf , il processo di formattazione della stringa dietro printf , e almeno una chiamata di sistema per scrivere effettivamente i dati, semplicemente reindirizzando stdout a /dev/null . Bene, questa è una vera differenza su Linux. L'implementazione restituisce solo il numero di byte che volevi scrivere (specificato dal terzo argomento della tua chiamata a write(2) ) e ignora tutto il resto (vedi questa risposta). A seconda della quantità di dati che stai scrivendo e della velocità del dispositivo di destinazione (disco o terminale), la differenza di prestazioni può variare molto. Sui sistemi embedded, in generale, interrompendo la scrittura su disco reindirizzando a /dev/null può far risparmiare parecchie risorse di sistema per una quantità non banale di dati scritti.

Anche se in teoria, il programma potrebbe rilevare /dev/null ed eseguire alcune ottimizzazioni entro le restrizioni degli standard a cui sono conformi (ISO C e POSIX), in base alla comprensione generale delle implementazioni comuni, praticamente non lo fanno (cioè non sono a conoscenza di alcun sistema Unix o Linux che lo faccia).

Lo standard POSIX impone la scrittura sullo standard output per qualsiasi chiamata a printf(3) , quindi non è conforme allo standard sopprimere la chiamata a write(2) a seconda dei descrittori di file associati. Per maggiori dettagli sui requisiti POSIX, puoi leggere la risposta di Damon. Oh, e una breve nota:tutte le distribuzioni Linux sono praticamente conformi a POSIX, nonostante non siano certificate essere così.

Tieni presente che se sostituisci printf completamente, alcuni effetti collaterali potrebbero andare storti, ad esempio printf("%d%n", a++, &b) . Se hai davvero bisogno di sopprimere l'output a seconda dell'ambiente di esecuzione del programma, prendi in considerazione l'impostazione di un flag globale e completa printf per controllare il flag prima della stampa:non rallenterà il programma in una misura in cui la perdita di prestazioni è visibile , poiché un singolo controllo di condizione è molto più veloce che chiamare printf e facendo tutta la formattazione della stringa.


Il printf la funzione sarà scrivi a stdout . Non è conforme all'ottimizzazione per /dev/null .Pertanto, avrai il sovraccarico di analizzare la stringa di formato e valutare tutti gli argomenti necessari, e avrai almeno una chiamata di sistema, inoltre copierai un buffer nello spazio degli indirizzi del kernel (che, rispetto al costo della chiamata di sistema è trascurabile ).

Questa risposta si basa sulla documentazione specifica di POSIX.

Interfacce di sistema
dprintf, fprintf, printf, snprintf, sprintf - stampa l'output formattato

La funzione fprintf() inserirà l'output nel flusso di output indicato. La funzione printf() inserirà l'output nel flusso di output standard stdout. La funzione sprintf() posizionerà l'output seguito dal byte nullo, '\0', in byte consecutivi a partire da *s; è responsabilità dell'utente assicurarsi che sia disponibile spazio sufficiente.

Definizioni di base
deve
Per un'implementazione conforme a POSIX.1-2017, descrive una funzionalità o un comportamento obbligatorio. Un'applicazione può fare affidamento sull'esistenza della funzionalità o del comportamento.


Linux
  1. Quando usare /dev/random vs /dev/urandom?

  2. Come reindirizzare l'output di un'applicazione in background a /dev/null

  3. Reindirizza stdout mentre un processo è in esecuzione:qual è il processo che invia a /dev/null

  4. echo o print /dev/stdin /dev/stdout /dev/stderr

  5. Perché sono necessari < o > per usare /dev/tcp

Che cos'è "/dev/null 2&1" in Linux

Come reindirizzare l'output su /dev/null in Linux

Che cos'è /dev/null in Linux

DD da /dev/zero a /dev/null... cosa succede realmente

Linux:differenza tra /dev/console , /dev/tty e /dev/tty0

Crea un dispositivo a blocchi virtuale che scrive su /dev/null