Todavía uso a menudo el resultado de la consola para obtener ideas sobre lo que está sucediendo en mi código. Sé que esto puede ser un poco pasada de moda, pero también usar esto para "tubo" stdout en los archivos de registro, etc.C: ¿Por qué un fprintf (stdout, ....) es tan lento?
Sin embargo, resulta que la salida de la consola se ralentiza por alguna razón . Me preguntaba si alguien puede explicar por qué una ventana de fprintf() a una consola parece ser una especie de bloqueo.
Lo que he hecho/diagnosticado hasta el momento:
Medí el tiempo de un simple
fprintf(stdout,"quick fprintf\n");
Se necesita: 0.82ms (en promedio). Esto se considera por mucho tiempo ya que unvsprintf_s(...)
escribe el mismo resultado en una cadena en solo unos pocos microsegundos. Por lo tanto, debe haber algún bloqueo específicamente para la consola.Para escapar del bloqueo, he usado
vsprintf_s(...)
para copiar mi salida en una estructura de datos igual a fifo. La estructura de datos está protegida por un objeto de sección crítico. Luego, un subproceso independiente recupera la estructura de datos colocando el resultado en cola en la consola.Otra mejora que pude obtener con la introducción de los servicios de tuberías. La salida de mi programa (se supone que terminan en una ventana de consola) va de la siguiente manera:
- Un
vsprintf_s(...)
formatea la salida a cadenas simples. - Las cadenas están en cola en una estructura de datos similar a fifo, una estructura de lista enlazada, por ejemplo. Esta estructura de datos está protegida por un objeto de sección crítico.
- Un segundo hilo dequeue la estructura de datos enviando las cadenas de salida a un conducto con nombre.
- Un segundo proceso lee la tubería con nombre y vuelve a poner las cadenas en una estructura de datos similar a fifo . Esto es necesario para mantener la lectura lejos de la salida de bloqueo de la consola. El proceso de lectura es rápido al leer la tubería con nombre y monitorea el nivel de llenado de la memoria intermedia de tuberías continuamente.
- Un segundo hilo en ese segundo proceso finalmente dequeues la estructura de datos por
fprintf(stdout,...)
a la consola.
- Un
Así que tienen dos procesos con al menos dos hilos cada uno, una tubería con nombre entre ellos, y estructuras de datos FIFO por igual en ambos lados de la tubería para evitar el bloqueo en caso de tampón tubería llena.
Eso es un montón de cosas para asegurarse de que la salida de la consola sea "no bloqueante". Pero el resultado es no está mal. Mi programa principal puede escribir fprintf complejo (stdout, ...) en tan solo unos pocos microsegundos.
Tal vez debería haber preguntado antes: ¿Hay alguna otra forma (más fácil) de tener salida de consola sin bloqueo?
Sospecho que es la consola la que está lenta. Los emuladores de terminal tienden a ser lentos (porque su velocidad en baudios es parte de sus especificaciones). ¿Mide el tiempo cuando redirecciona * stdout * a algún archivo? Y podría enviar información de depuración a otro 'FILE' (y usar' setvbuf' con un gran buffer). –
¿Con qué sistema operativo, bibliotecas, compilador está trabajando? –
La cantidad de tiempo que toma 'fprintf' no es muy interesante si no sabe cuánto de ese tiempo se usa para esperar al canal de salida. –