|
Profiler=Good, RichTextBox=Bad 29 Aug 2003
Call me a fan of the Ants Profiler from Red
Gate Software.
Our top priority at SourceGear right now is making Vault faster. I
don't get to do much coding these days, so I decided to get my hands dirty and
pitch in. Several of the other folks here have been using Ants to profile
Vault, so I thought I would give it a try. The tool was extremely
smooth. I installed it with no problems. I didn't read a word of the
documentation. I launched the profiler and told it to profile the Vault
GUI client EXE. I did my test and exited the Vault client. Ants
showed me the results.
The results browser is cool. I cruised around the various functions and
examined the timings. Soon I discovered one of those problems which
profilers were born to find: The .NET RichTextBox class is really, really
slow.
We use a RichTextBox to display user messages in a pane at the bottom of the
Vault client window. I suppose any plain text box would suffice, but we do
use a little bit of color for highlighting errors in red. Anyway, the
profiler was showing that Vault spends an obscene amount of time showing user
progress messages. My test case involved the retrieval of 6,000 files from
a repository, which means I was adding 6,000 messages to that RichTextBox.
At first I suspected string concatenation. The code to append messages
looked something like this:
AppendText("["+msg.When+"] "+msg.Message+"\r\n");
So I
changed it to eliminate the string concatenation:
AppendText("["); AppendText(msg.When); AppendText("]
"); AppendText(msg.Message); AppendText("\r\n");
This made no real difference in
performance, but the profiler results became even more useful. Ants
can show how much time is being spent on each line of code. When I broke
things up, Ants reported that the first four calls to AppendText were fast, and
the fifth one was slow. Then I realized what's going on. When you
append a CRLF to the RichTextBox, it's re-running its internal layout
algorithm.
RichTextBox is obviously overkill for the way we are using it. It's not
like we need full justification or embedded tables in our user messages
pane, but we're paying for these features in performance. This
innocent-looking piece of the .NET framework is actually a word
processor.
The problem was easily fixed.
Instead of calling AppendText() on every single message, I batched up the
non-urgent messages into groups so we could append them with a single
call. Much faster, no lost functionality, everybody will be
happier.
|