PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : VB60: Eigener Editor mit Synt. Highlighting --> optmieren


Kinman
2004-11-30, 22:07:31
Hi, ich schreibe gerade einen PHP Editor. Natürlich möchte ich Syntaxhighlighting unterstützen. Ich hab auch schon passenden Code entwickelt. Jedoch wird er bei größeren Files ziehmlich langsam. Was könnte man hier optimieren?

searchWord und wordColor sind Arrays in dem die zu färbenden Worte & die Farben drinstehen.


Public Sub colorizeTags(ByRef rtfField As RichTextBox)
On Error Resume Next
Dim oldPos, tmpPos, i As Integer
Dim tmpStr As String

oldPos = rtfField.SelStart
tmpPos = 0
tmpStr = ""
rtfField.Visible = False

rtfField.SelStart = 0
rtfField.SelLength = Len(rtfField.Text)
rtfField.SelColor = stdColor

For i = 0 To UBound(searchWord) Step 1
searchWord(i) = Trim$(searchWord(i))
tmpPos = 0
If searchWord(i) <> "" Then
While rtfField.Find(searchWord(i), tmpPos) <> -1
tmpStr = Left$(rtfField.Text, rtfField.SelStart)

If CountSigns(tmpStr, Chr(34)) Mod 2 = 0 Then '34 --> "
If CountSigns(rtfField.Text, Chr(39)) Mod 2 = 0 Then '39 --> '
rtfField.SelColor = wordColor(i)
End If
End If

tmpPos = rtfField.SelStart
rtfField.SelStart = rtfField.SelStart + rtfField.SelLength
rtfField.SelColor = stdColor
tmpPos = tmpPos + 1
Wend
End If
Next i

rtfField.Visible = True


rtfField.SetFocus
rtfField.SelStart = rtfField.SelStart + rtfField.SelLength
rtfField.SelColor = stdColor
rtfField.SelStart = oldPos
rtfField.SelLength = 0

End Sub

Und hier die Funktion CountSigns:

Public Function CountSigns(ByVal sText As String, ByVal sFindThis As String, Optional ByVal bCaseSensitiv As Boolean = False) As Long
Dim nSigns As Long
Dim nSearchLen As Long

If Len(sFindThis) = 0 Then CountSigns = -1: Exit Function

nSigns = Len(sText)
nSearchLen = Len(sFindThis)

If bCaseSensitiv Then
sText = Replace(sText, sFindThis, "")
Else
sText = Replace(LCase$(sText), LCase$(sFindThis), "")
End If

CountSigns = (nSigns - Len(sText)) / nSearchLen
End Function


Ich bin für jegliche Hilfe sehr dankbar.

mfg Kinman

Trap
2004-11-30, 22:34:38
2 lowlevel Optimierungen:
1. Nicht für jedes Suchwort die komplette Datei durchsuchen, sondern für jedes Zeichen alle Suchworte die mit diesem Zeichen beginnen testen.
2. Nur Teile neu färben die sich verändert haben.

Kinman
2004-11-30, 22:38:45
zu 1. ich glaube viele string compares sind langsamer als die datei zu suchen, da eh alles im speicher steht :D

zu 2. hab ich mir auch schon gedacht, jedoch fehlt bisher eine idee für einen gscheiden ansatz..
----
Danke trotzdem, werd mir das noch mal genau durch den kopf gehen lassen
(mittlerweile färb ich nur noch bei verlassen der aktuellen zeile und bei focus-lost)

btw. ich glaube das langsamste ist die find Methode des RTFs

mfg Kinman

Trap
2004-11-30, 22:48:03
m=Anzahl der Suchwörter
n=Anzahl der Zeichen

Dein Algorithmus hat n*m Stringvergleiche (oder was meinst du wie find sonst funktionieren soll?). Mein Vorschlag hat viel weniger.

Kinman
2004-11-30, 23:07:46
kann sein das ich das jetz falsch seh, aber ich verstehs so:
m=Suchwörter
n=Anzahl aller Wörter
und dann m*n
Aber das hängt natürlich davon ab wie die find Methode aufgebaut ist.
Ich werde deine Idee morgen oder übermorgen mal auspobieren, thx

mfg Kinman

Trap
2004-11-30, 23:18:35
Wichtig ist bei der Implementierung, dass man die Suchwörter die mit dem aktuellen Zeichen anfangen schnell finden kann. Entweder indem man alle Suchwörter sortiert und dann binär sucht (gibt O(log n)) oder besser indem man eine Tabelle (ein Array) nimmt in der für jedes Zeichen alle Suchwörter die mit diesem Zeichen beginnen eingetragen sind (gibt O(1)).
Wenn du es noch schneller machen willst kannst du eine Tabelle über alle 2-Zeichen-Kombinationen nehmen mit den dazugehörigen Suchworten. Das geht allerdings nur bei 8-Bit Zeichen, bei 16-Bit Zeichen ist schon eine Tabelle für 1 Zeichen sehr groß.

Kinman
2004-12-06, 22:05:20
danke, ich bin das ganze umgangen und habe mittels collections sog. look-up tables gemacht. Ist auf jedenfall schnell genug weil die methode find weg ist, und das war absolut das langsamste.

Danke nochmal, mfg Kinman