Acceleration of text output in Windows, for the console

We have an application that has one or more text console windows that are essentially serial ports (text input and output, character by character). These windows have become a major performance issue as they are now in the code ... we manage to spend a very significant chunk of our time on them.

The current code is structured due to the fact that the window lives its own small life, and the main application thread manages it through SendMessage () calls. This messaging seems to be causing an incredible overhead. Basically, having a bypass through the OS seems to be wrong.

Note that we draw text lines in general when needed to make optimization easier.

I'm not an expert on Windows coding, so I need to ask the community if there is any other architecture for displaying text in a window than sending messages like this? This seems pretty cumbersome.

Note that this is in C ++ or just C, as the main application is a portable C / C ++ / some other languages ​​program that also works on Linux and Solaris.

We did some more research, it seems that half of the overhead prepares and sends each message with SendMessage, and the other half is the actual screen drawing. SendMessage is executed between functions in the same file ...

So, I think all of the recommendations below are correct:

  • See how much has been redrawn.
  • Draw things directly.
  • Draw slice operations over time to avoid sending every character to the screen in order to increase the refresh rate from 10 to 20 Hz on the serial console.

Can you accept ALL of the answers?

+1


source to share


4 answers


I agree with Will Dean that drawing in a console window or text box is a performance bottleneck. First, you need to be sure that this is not your problem. You say you are drawing each line as a whole, but even that can be a problem if the data throughput is too high.



I recommend not using SendMessage to send data from the main application to the text box. Use other means of communication instead. Are they in the same process? If not, you can use shared memory. Even a file on disk can work in some cases. Ask the main application to write to this file, and ask the text console to read. You can send a SendMessage notification to the text console to communicate this to update the view. But don't send a message every time a new line comes in. Determine the minimum interval between two subsequent updates.

+1


source


You should try to profile it correctly, but instead I'll stop worrying about SendMessage, which is almost certainly not your problem, and consider redrawing the window itself.

You describe it as "text console windows", but then say that you have several - are they actually Windows consoles? Or is this what your application draws?



If the latter, then I would look at the dimension of my drawing code and whether I was invalidating too many windows for each update.

+1


source


Are the output windows part of the same application? It almost looks like they're not ...

If so, you should look into the Observer design pattern to get away with SendMessage (). I've used it for the same type of use and it worked great for me.

If you can't make a change like this, perhaps you can buffer your output to something like 100ms so you don't have that many outgoing messages per second, but it should also refresh at a comfortable rate.

+1


source


Are output windows part of the same application? It almost sounds like they're not ...

Yes, they are all in one process.

I didn't write this code ... but it looks like SendMessage is a bit heavy for all of this in one application.

You describe these as "text console" windows, but then say you have several of them - are they actually Windows Consoles? Or are they drawing something to your application?

Our application draws them, they are not regular Windows consoles.

Note that we also need to return data when the user enters into the console, as we often have interactive sequential sessions. Think how this is very similar to what you will see in a serial terminal program, but using an external application is obviously even more expensive than we have now.

If you can't make such a change, perhaps you can buffer your output for something like 100ms so you don't have many current messages per second, but it should also update at a comfortable rate.

Good point. Right now, every single output of a character triggers a message to be sent.

And when we scroll the window up, when a new line appears, we redraw it in turn.

Note that we also have an arbitrary size scroll buffer, but scrolling back is an interactive case with much lower performance requirements.

0


source







All Articles