0

I realize a program which basically imports data. The log of the import is built with a StringBuilder, and then printed in a RichTextBox, programmaticaly, in a new Window.

I searched how to hightlight specific words and how to put in bold lines containing specific characters.

For example, part of my log looks like this :

Screenshot

I didn't found a "magic solution" in WPF for this, so I made a code which is not very optimized / proper. This is my code :

TextRange tr;
foreach(var line in finalText.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)
{
    tr = new TextRange(rtb.Document.ContentEnd, rtb.Document.ContentEnd);

    foreach (var word in line.Split(' '))
    {
        tr = new TextRange(rtb.Document.ContentEnd, rtb.Document.ContentEnd);
        tr.Text = word + ' ';

        if (line.IndexOf("====", StringComparison.OrdinalIgnoreCase) >= 0)
        {
            tr.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Bold);
        }
        else if (line.IndexOf("Statut", StringComparison.OrdinalIgnoreCase) >= 0)
        {
            tr.ApplyPropertyValue(TextElement.FontSizeProperty, (double)14);
        }
        else if (line.IndexOf("Fin", StringComparison.OrdinalIgnoreCase) >= 0)
        {
            tr.ApplyPropertyValue(TextElement.FontSizeProperty, (double)14);
        }
        else
        {
            tr.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Normal);
            tr.ApplyPropertyValue(TextElement.FontSizeProperty, (double)12);
        }

        if (word.IndexOf("Succès", StringComparison.OrdinalIgnoreCase) >= 0 || word.IndexOf("Succes", StringComparison.OrdinalIgnoreCase) >= 0)
        {
            tr.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.Green);
        }
        else if (word.IndexOf("Erreur", StringComparison.OrdinalIgnoreCase) >= 0)
        {
            tr.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.Red);
        }
        else if (word.IndexOf("Info", StringComparison.OrdinalIgnoreCase) >= 0)
        {
            tr.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.DarkOrange);
        }
        else if (word.IndexOf("Modif", StringComparison.OrdinalIgnoreCase) >= 0)
        {
            tr.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.DarkBlue);
        }
        else
        {
            tr.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.Black);
        }
    }
    tr.Text += Environment.NewLine;
}

Note : finalText is the String representing the log and rtb is the RichTextBox.

As you can see when a entire line needs to be in bold, I re-apply the property to each word because I need a new TextRange for each new word, in order to change the color.

The problem is that with only a few lines of log (let's say 50 lines), I found my code to be very slow : this single piece of code takes up to 3 seconds to complete. The import itself (opening files, analyzing, making operations in database on a lot of data) does not take such time.

Any hint to reduce this time ?

Thank you in advance.

Chostakovitch
  • 965
  • 1
  • 9
  • 33
  • You should use a profiling tool to find out which parts of your program are actually causing the slow down. It should break down each function by the amount of time that the CPU spend in each. That will give you the best idea of where you should spend your time optimizing. It will also give you a REAL number to compare results to so that you know if your changes are actually making a difference. There is some build in profiling support in Visual Studio under the "Analyze" menu. – Bradley Uffner Apr 23 '15 at 13:43
  • @BradleyUffner I'm sure this is this piece of code (I measured it with `StopWatch`). But if I can isolate even more, can you tell me which profiling tool I should use for example ? – Chostakovitch Apr 23 '15 at 13:45
  • A profiler will tell you specifically if it's the string concatination, all the calls to ApplyPropertyValue, or even the string.Split call that is slowing you down. I'd start with the profiler built in to Visual Studio. – Bradley Uffner Apr 23 '15 at 13:47
  • This link should give you a good idea of how to use the profiler. https://msdn.microsoft.com/en-us/library/ms182372.aspx – Bradley Uffner Apr 23 '15 at 13:49
  • @BradleyUffner Unfortunatly, according to this link ( https://msdn.microsoft.com/en-us/library/ms182372%28v=vs.100%29.aspx ), I can't use the profiler. I only have the 2010 Profesionnal version. Do you have any other idea ? – Chostakovitch Apr 23 '15 at 13:52
  • Check out this option to run it stand alone. http://stackoverflow.com/questions/6852417/profiling-in-visual-studio-2010-professional – Bradley Uffner Apr 23 '15 at 13:55
  • Try setting the Visibility property to Hidden while this code runs. – Hans Passant Apr 23 '15 at 13:57
  • @HansPassant It has no effect. – Chostakovitch Apr 23 '15 at 14:01
  • @BradleyUffner I've done it, but I can't understand the generated files. The functions are just numbers and the files are too big. – Chostakovitch Apr 23 '15 at 14:15
  • Try this one https://code.google.com/p/slimtune/ – Bradley Uffner Apr 23 '15 at 14:16
  • @BradleyUffner It works; but I don't see where I can collect interesting data. The only thing I found is that : http://puu.sh/ho3tz/d90c18ea9b.png – Chostakovitch Apr 23 '15 at 14:30

0 Answers0