[C#] a bissle schneller... (RichTextBox + TextHighlight)



  • Servus,

    kleine Problemchen. Ich habe eine RichTextBox in der ich Text aus einer Datei lade. Nach dem Laden möchte ich gerne bestimmte Schlüsselwörter hervorheben. Das ist ja alles kein Problem:

    int iPos = -1;
    string strText = string.Empty;
    string strRichText = ScriptTextBox.Text;
    for (int i = 0; i < m_arrSearchList.Count; i++)
    {
    	strText = m_arrSearchList[i].ToString();
    	while ((iPos = strRichText.IndexOf(strText, iPos+1)) > -1)
    	{				
    		ScriptTextBox.Select(iPos, strText.Length);
    		ScriptTextBox.SelectionColor = Color.Red;
    	}
    }
    

    strRichText = Text aus der RichTextBox
    ScriptTextBox = RichTextBox
    m_arrSearchList = ArrayList beinhaltet ca. 200 Schlüsselwörter

    In dem Codeschnipsel suche ich nach den Schlüsselwörter und markiere diese rot. Nun dauert es bei einer 15kb (ca 200 Zeilen) ca. 3 Sekunden bis er alles durchgegangen ist. Nicht schlimm, aber vielleicht ist es doch verbesserungswürdig.

    Hat hier vielleicht jemand eine Idee, wie man diesen Schnipsel ein bisschen optimieren kann???? Für konstruktive Beiträge bin sehr dankbar. Für den Rest auch 😃

    *winke*
    Hellsgore



  • Hoi.
    Beschäftige dich mit dem Rtf-Format. Dann kannst du ganz einfach deine Formattierungen direkt im Format vornehmen. Über die Eigenschaft Rtf bekommst du den "Quellcode" als System::String. Dort kannst du via RegEx, Stringbuilder und Replace die zu formattierenden Einträge modifizieren. Das geht vielleicht schneller... 👍



  • Statt for wäre ein foreach schöner.
    Ist deine ArrayList nicht generisch, so dass du dir den Pseudo-Cast mit ToString() sparen kannst?
    Machen wir erstmal den Code ein bisschen schöner:

    string strRichText = ScriptTextBox.Text;
    // Unter der Annahme, dass die ArrayList generisch ist
    foreach( string strText in m_arrSearchList )
        while( (int iPos = strRichText.IndexOf(strText, iPos+1)) > -1 )
        {               
            ScriptTextBox.Select(iPos, strText.Length);
            ScriptTextBox.SelectionColor = Color.Red;
        }
    

    So, jetzt erst kann ich überhaupt mal dran denken, einen besseren Algorithmus zu finden. Vorher war mir das leider nicht möglich. Jetzt muss ich aber leider weiterarbeiten, sonst stampft mich mein Chef ein.
    Bis nachher...



  • Er will den Code schneller, nicht schöner machen. Und foreach würde das ganze nur noch langsamer machen.



  • Wo hast du denn diesen Schwachsinn her? Meine Güte, Jung! Hier gibt es ein inhärentes Problem. Wenn der Text 10mal so lang wird, braucht das Teil 10mal so lange. Und foreach ist daran nicht schuld. Null Ahnung.



  • Optimizer schrieb:

    string strRichText = ScriptTextBox.Text;
    // Unter der Annahme, dass die ArrayList generisch ist
    foreach( string strText in m_arrSearchList )
        while( (int iPos = strRichText.IndexOf(strText, iPos+1)) > -1 )
        {               
            ScriptTextBox.Select(iPos, strText.Length);
            ScriptTextBox.SelectionColor = Color.Red;
        }
    

    Musst du die Color in jedem Schleifendurchlauf setzen? Wenn das einmal reicht, hast du die "lahme" foreach schon ausgeglichen. 🙄
    Evtl. hilft auch eine ganz andere heranggehensweise. Anstatt m_arrSearchList.Count-mal über den Text zu gehen, vielleicht tokenweise arbeiten und nur einmal durchgehen. Hängt natürlich sehr davon ab, was du für annahmen über deine Schlüsselworte machen kannst, ob sie stets ein eigenes Token sind, usw.



  • Servus,

    schankedön für eure Ratschläge. Habe mir den Vorschlag von phoenix mal genauer angesehen. Nun hole ich mir einfach den Text im RTF Format und setze in diesem dann die Steuerzeichen für Formatierungen, Farben etc. Mit String.Replace() gehts wunderbar und schnell *g*. 200kb Textdatei habe ich nun in 0.8Sekunden formatiert.

    Schankedön...

    *winke*
    Hellsgore


Anmelden zum Antworten