C: Why is fprintf (stdout, ....) so slow?

I still often use console output to find out what is going on in my code. I know this may be a bit of an old fashion, but I also use this for the "pipe" stdout in log files, etc.

However, it appears that console output is slowing down for some reason. I was wondering if anyone could explain why fprintf () on the console window seems to be a kind of lock.

What I have done / diagnosed so far:

  • I measured the time of a simple fprintf(stdout,"quick fprintf\n"); It should: 0.82 ms (average). This has been considered too long since vsprintf_s(...) writes the same output to a string in just a few microseconds. Therefore, there must be some kind of lock for the console.

  • Otherwise, to avoid blocking, I used vsprintf_s(...) to copy my output to the same data structure. The data structure is protected by a critical partition object. Then a separate thread discards the data structure, placing the output in a queue on the console.

  • Another improvement that I could get through the introduction of pipe services. The output of my program (supposedly ends in the console window) is as follows:

    • A vsprintf_s(...) formats output to simple strings.
    • Rows are placed in the same data structure, for example, in the structure of linked lists. This data structure is protected by a critical partition object.
    • The second thread deletes the data structure by sending output strings to the named pipe.
    • The second process reads the named pipe and again puts the lines in the data, similar to the fifo composition. This is necessary in order to remove reading from the lock output to the console. The read process quickly reads the named pipe and continuously monitors the buffer fill level.
    • The second thread in this second process permanently deletes the data structure using fprintf(stdout,...) to the console.

So, I have two processes with at least two threads each, a named pipe between them and fifo file structures on both sides of the channel, to avoid blocking if the channel buffer is full.

This is just a lot to just make sure the console output is "non-blocking." But the result is not bad. My main program can write complex fprintf (stdout, ...) in just a few microseconds.

Perhaps I should have asked earlier: is there any other (easier!) Way to output non-blocking consoles?

+9
c
Jul 19 '12 at 10:09
source share
1 answer

I think the synchronization problem is due to the fact that the console is configured by default by default. This means that every time you write the character '\n' , your entire output buffer is sent to the console, which is quite an expensive operation. This is the price you pay for the line immediately appearing on the output.

You can change this default behavior by changing the buffering strategy to full buffering. The consequence is that the output will be sent to the console in chunks that are equal to the size of your buffer, but certain operations will be faster.

Make this call before you first enter the console:

 char buf[10000]; setvbuf(stdout, buf, _IOFBF, sizeof(buf)); 

The time of individual entries should improve, but the result will not appear on the console immediately. This is not very useful for debugging, but time will improve. If you set up a stream that calls fflush(stdout) at regular time intervals, say, once per second, you should get a reasonable balance between the performance of individual records and the delay between your program that writes the output and the time that you can actually see its on the console.

+12
Jul 19 '12 at 10:32
source share



All Articles