Bastante.
Cuando redirige la salida estándar del programa a /dev/null
, cualquier llamada a printf(3)
seguirá evaluando todos los argumentos, y el proceso de formateo de cadenas seguirá teniendo lugar antes de llamar a write(2)
, que escribe la cadena con formato completo en la salida estándar del proceso. Es en el nivel del núcleo donde los datos no se escriben en el disco, sino que el controlador asociado con el dispositivo especial los descarta /dev/null
.
Entonces, en el mejor de los casos, no omitirá ni evadirá la sobrecarga de evaluar los argumentos y pasarlos a printf
, el trabajo de formato de cadena detrás de printf
, y al menos una llamada al sistema para escribir los datos, simplemente redirigiendo stdout a /dev/null
. Bueno, esa es una verdadera diferencia en Linux. La implementación solo devuelve la cantidad de bytes que desea escribir (especificado por el tercer argumento de su llamada a write(2)
) e ignora todo lo demás (ver esta respuesta). Según la cantidad de datos que esté escribiendo y la velocidad del dispositivo de destino (disco o terminal), la diferencia en el rendimiento puede variar mucho. En los sistemas integrados, por lo general, cortar la escritura del disco redirigiendo a /dev/null
puede ahorrar bastantes recursos del sistema para una cantidad no trivial de datos escritos.
Aunque en teoría, el programa podría detectar /dev/null
y realizar algunas optimizaciones dentro de las restricciones de los estándares que cumplen (ISO C y POSIX), según la comprensión general de las implementaciones comunes, prácticamente no lo hacen (es decir, no tengo conocimiento de que ningún sistema Unix o Linux lo haga).
El estándar POSIX exige escribir en la salida estándar para cualquier llamada a printf(3)
, por lo que no cumple con los estándares suprimir la llamada a write(2)
dependiendo de los descriptores de archivo asociados. Para obtener más detalles sobre los requisitos de POSIX, puede leer la respuesta de Damon. Ah, y una nota rápida:todas las distribuciones de Linux son prácticamente compatibles con POSIX, a pesar de no estar certificadas. ser así.
Tenga en cuenta que si reemplaza printf
completamente, algunos efectos secundarios pueden salir mal, por ejemplo printf("%d%n", a++, &b)
. Si realmente necesita suprimir la salida según el entorno de ejecución del programa, considere establecer un indicador global y termine printf para verificar el indicador antes de imprimir; no ralentizará el programa hasta el punto en que la pérdida de rendimiento sea visible. , ya que la verificación de una sola condición es mucho más rápido que llamar al printf
y haciendo todo el formato de cadena.
El printf
función voluntad escribe a stdout
. No se ajusta a optimizar para /dev/null
.Por lo tanto, tendrá la sobrecarga de analizar la cadena de formato y evaluar los argumentos necesarios, y tendrá al menos una llamada al sistema, además de copiar un búfer en el espacio de direcciones del núcleo (que, en comparación con el costo de la llamada al sistema, es insignificante ).
Esta respuesta se basa en la documentación específica de POSIX.
Interfaces del sistema
dprintf, fprintf, printf, snprintf, sprintf - salida con formato de impresión
La función fprintf() colocará la salida en el flujo de salida nombrado. La función printf() colocará la salida en el flujo de salida estándar stdout. La función sprintf() colocará la salida seguida del byte nulo, '\0', en bytes consecutivos comenzando con *s; es responsabilidad del usuario asegurarse de que haya suficiente espacio disponible.
Definiciones básicas
deberá
Para una implementación que cumple con POSIX.1-2017, describe una característica o comportamiento que es obligatorio. Una aplicación puede confiar en la existencia de la función o el comportamiento.